if_rsu.c (283540) | if_rsu.c (286410) |
---|---|
1/* $OpenBSD: if_rsu.c,v 1.17 2013/04/15 09:23:01 mglocker Exp $ */ 2 3/*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18#include <sys/cdefs.h> | 1/* $OpenBSD: if_rsu.c,v 1.17 2013/04/15 09:23:01 mglocker Exp $ */ 2 3/*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18#include <sys/cdefs.h> |
19__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rsu.c 283540 2015-05-25 19:53:29Z glebius $"); | 19__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rsu.c 286410 2015-08-07 11:43:14Z glebius $"); |
20 21/* 22 * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU. 23 * 24 * TODO: 25 * o 11n support 26 * o h/w crypto 27 * o hostap / ibss / mesh --- 154 unchanged lines hidden (view full) --- 182 rsu_rx_frame(struct rsu_softc *, uint8_t *, int, int *); 183static struct mbuf * 184 rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int, int *); 185static struct mbuf * 186 rsu_rxeof(struct usb_xfer *, struct rsu_data *, int *); 187static void rsu_txeof(struct usb_xfer *, struct rsu_data *); 188static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, 189 const struct ieee80211_bpf_params *); | 20 21/* 22 * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU. 23 * 24 * TODO: 25 * o 11n support 26 * o h/w crypto 27 * o hostap / ibss / mesh --- 154 unchanged lines hidden (view full) --- 182 rsu_rx_frame(struct rsu_softc *, uint8_t *, int, int *); 183static struct mbuf * 184 rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int, int *); 185static struct mbuf * 186 rsu_rxeof(struct usb_xfer *, struct rsu_data *, int *); 187static void rsu_txeof(struct usb_xfer *, struct rsu_data *); 188static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, 189 const struct ieee80211_bpf_params *); |
190static void rsu_init(void *); 191static void rsu_init_locked(struct rsu_softc *); | 190static void rsu_init(struct rsu_softc *); |
192static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, 193 struct mbuf *, struct rsu_data *); | 191static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, 192 struct mbuf *, struct rsu_data *); |
194static void rsu_start(struct ifnet *); 195static void rsu_start_locked(struct ifnet *); 196static int rsu_ioctl(struct ifnet *, u_long, caddr_t); 197static void rsu_stop(struct ifnet *, int); 198static void rsu_stop_locked(struct ifnet *, int); | 193static int rsu_transmit(struct ieee80211com *, struct mbuf *); 194static void rsu_start(struct rsu_softc *); 195static void rsu_parent(struct ieee80211com *); 196static void rsu_stop(struct rsu_softc *); |
199static void rsu_ms_delay(struct rsu_softc *); 200 201static device_method_t rsu_methods[] = { 202 DEVMETHOD(device_probe, rsu_match), 203 DEVMETHOD(device_attach, rsu_attach), 204 DEVMETHOD(device_detach, rsu_detach), 205 206 DEVMETHOD_END --- 73 unchanged lines hidden (view full) --- 280 return (usbd_lookup_id_by_uaa(rsu_devs, sizeof(rsu_devs), uaa)); 281} 282 283static int 284rsu_attach(device_t self) 285{ 286 struct usb_attach_arg *uaa = device_get_ivars(self); 287 struct rsu_softc *sc = device_get_softc(self); | 197static void rsu_ms_delay(struct rsu_softc *); 198 199static device_method_t rsu_methods[] = { 200 DEVMETHOD(device_probe, rsu_match), 201 DEVMETHOD(device_attach, rsu_attach), 202 DEVMETHOD(device_detach, rsu_detach), 203 204 DEVMETHOD_END --- 73 unchanged lines hidden (view full) --- 278 return (usbd_lookup_id_by_uaa(rsu_devs, sizeof(rsu_devs), uaa)); 279} 280 281static int 282rsu_attach(device_t self) 283{ 284 struct usb_attach_arg *uaa = device_get_ivars(self); 285 struct rsu_softc *sc = device_get_softc(self); |
288 struct ifnet *ifp; 289 struct ieee80211com *ic; | 286 struct ieee80211com *ic = &sc->sc_ic; |
290 int error; 291 uint8_t iface_index, bands; 292 293 device_set_usb_desc(self); 294 sc->sc_udev = uaa->device; 295 sc->sc_dev = self; 296 297 mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, 298 MTX_DEF); 299 TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, 300 rsu_calib_task, sc); | 287 int error; 288 uint8_t iface_index, bands; 289 290 device_set_usb_desc(self); 291 sc->sc_udev = uaa->device; 292 sc->sc_dev = self; 293 294 mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, 295 MTX_DEF); 296 TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, 297 rsu_calib_task, sc); |
298 mbufq_init(&sc->sc_snd, ifqmaxlen); |
|
301 302 /* Allocate Tx/Rx buffers. */ 303 error = rsu_alloc_rx_list(sc); 304 if (error != 0) { 305 device_printf(sc->sc_dev, "could not allocate Rx buffers\n"); 306 goto fail_usb; 307 } 308 --- 19 unchanged lines hidden (view full) --- 328 if (sc->cut != 3) 329 sc->cut = (sc->cut >> 1) + 1; 330 error = rsu_read_rom(sc); 331 RSU_UNLOCK(sc); 332 if (error != 0) { 333 device_printf(self, "could not read ROM\n"); 334 goto fail_rom; 335 } | 299 300 /* Allocate Tx/Rx buffers. */ 301 error = rsu_alloc_rx_list(sc); 302 if (error != 0) { 303 device_printf(sc->sc_dev, "could not allocate Rx buffers\n"); 304 goto fail_usb; 305 } 306 --- 19 unchanged lines hidden (view full) --- 326 if (sc->cut != 3) 327 sc->cut = (sc->cut >> 1) + 1; 328 error = rsu_read_rom(sc); 329 RSU_UNLOCK(sc); 330 if (error != 0) { 331 device_printf(self, "could not read ROM\n"); 332 goto fail_rom; 333 } |
336 IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]); | 334 IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->rom[0x12]); |
337 device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut); | 335 device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut); |
338 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 339 if (ifp == NULL) { 340 device_printf(self, "cannot allocate interface\n"); 341 goto fail_ifalloc; 342 } 343 ic = ifp->if_l2com; 344 ifp->if_softc = sc; 345 if_initname(ifp, "rsu", device_get_unit(self)); 346 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 347 ifp->if_init = rsu_init; 348 ifp->if_ioctl = rsu_ioctl; 349 ifp->if_start = rsu_start; 350 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 351 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 352 IFQ_SET_READY(&ifp->if_snd); 353 ifp->if_capabilities |= IFCAP_RXCSUM; 354 ifp->if_capenable |= IFCAP_RXCSUM; 355 ifp->if_hwassist = CSUM_TCP; | |
356 | 336 |
357 ic->ic_ifp = ifp; | |
358 ic->ic_softc = sc; 359 ic->ic_name = device_get_nameunit(self); 360 ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */ 361 ic->ic_opmode = IEEE80211_M_STA; /* Default to BSS mode. */ 362 363 /* Set device capabilities. */ 364 ic->ic_caps = 365 IEEE80211_C_STA | /* station mode */ --- 16 unchanged lines hidden (view full) --- 382#endif 383 384 /* Set supported .11b and .11g rates. */ 385 bands = 0; 386 setbit(&bands, IEEE80211_MODE_11B); 387 setbit(&bands, IEEE80211_MODE_11G); 388 ieee80211_init_channels(ic, NULL, &bands); 389 | 337 ic->ic_softc = sc; 338 ic->ic_name = device_get_nameunit(self); 339 ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */ 340 ic->ic_opmode = IEEE80211_M_STA; /* Default to BSS mode. */ 341 342 /* Set device capabilities. */ 343 ic->ic_caps = 344 IEEE80211_C_STA | /* station mode */ --- 16 unchanged lines hidden (view full) --- 361#endif 362 363 /* Set supported .11b and .11g rates. */ 364 bands = 0; 365 setbit(&bands, IEEE80211_MODE_11B); 366 setbit(&bands, IEEE80211_MODE_11G); 367 ieee80211_init_channels(ic, NULL, &bands); 368 |
390 ieee80211_ifattach(ic, sc->sc_bssid); | 369 ieee80211_ifattach(ic); |
391 ic->ic_raw_xmit = rsu_raw_xmit; 392 ic->ic_scan_start = rsu_scan_start; 393 ic->ic_scan_end = rsu_scan_end; 394 ic->ic_set_channel = rsu_set_channel; 395 ic->ic_vap_create = rsu_vap_create; 396 ic->ic_vap_delete = rsu_vap_delete; 397 ic->ic_update_mcast = rsu_update_mcast; | 370 ic->ic_raw_xmit = rsu_raw_xmit; 371 ic->ic_scan_start = rsu_scan_start; 372 ic->ic_scan_end = rsu_scan_end; 373 ic->ic_set_channel = rsu_set_channel; 374 ic->ic_vap_create = rsu_vap_create; 375 ic->ic_vap_delete = rsu_vap_delete; 376 ic->ic_update_mcast = rsu_update_mcast; |
377 ic->ic_parent = rsu_parent; 378 ic->ic_transmit = rsu_transmit; |
|
398 399 ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, 400 sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT, 401 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 402 RSU_RX_RADIOTAP_PRESENT); 403 404 if (bootverbose) 405 ieee80211_announce(ic); 406 407 return (0); 408 | 379 380 ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, 381 sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT, 382 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 383 RSU_RX_RADIOTAP_PRESENT); 384 385 if (bootverbose) 386 ieee80211_announce(ic); 387 388 return (0); 389 |
409fail_ifalloc: | |
410fail_rom: 411 usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); 412fail_usb: 413 mtx_destroy(&sc->sc_mtx); 414 return (ENXIO); 415} 416 417static int 418rsu_detach(device_t self) 419{ 420 struct rsu_softc *sc = device_get_softc(self); | 390fail_rom: 391 usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); 392fail_usb: 393 mtx_destroy(&sc->sc_mtx); 394 return (ENXIO); 395} 396 397static int 398rsu_detach(device_t self) 399{ 400 struct rsu_softc *sc = device_get_softc(self); |
421 struct ifnet *ifp = sc->sc_ifp; 422 struct ieee80211com *ic = ifp->if_l2com; | 401 struct ieee80211com *ic = &sc->sc_ic; |
423 | 402 |
424 rsu_stop(ifp, 1); | 403 RSU_LOCK(sc); 404 rsu_stop(sc); 405 RSU_UNLOCK(sc); |
425 usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); 426 ieee80211_ifdetach(ic); 427 428 taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task); 429 430 /* Free Tx/Rx buffers. */ 431 rsu_free_tx_list(sc); 432 rsu_free_rx_list(sc); 433 | 406 usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); 407 ieee80211_ifdetach(ic); 408 409 taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task); 410 411 /* Free Tx/Rx buffers. */ 412 rsu_free_tx_list(sc); 413 rsu_free_rx_list(sc); 414 |
434 if_free(ifp); | 415 mbufq_drain(&sc->sc_snd); |
435 mtx_destroy(&sc->sc_mtx); 436 437 return (0); 438} 439 440static usb_error_t 441rsu_do_request(struct rsu_softc *sc, struct usb_device_request *req, 442 void *data) --- 23 unchanged lines hidden (view full) --- 466 const uint8_t mac[IEEE80211_ADDR_LEN]) 467{ 468 struct rsu_vap *uvp; 469 struct ieee80211vap *vap; 470 471 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 472 return (NULL); 473 | 416 mtx_destroy(&sc->sc_mtx); 417 418 return (0); 419} 420 421static usb_error_t 422rsu_do_request(struct rsu_softc *sc, struct usb_device_request *req, 423 void *data) --- 23 unchanged lines hidden (view full) --- 447 const uint8_t mac[IEEE80211_ADDR_LEN]) 448{ 449 struct rsu_vap *uvp; 450 struct ieee80211vap *vap; 451 452 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 453 return (NULL); 454 |
474 uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap), 475 M_80211_VAP, M_NOWAIT | M_ZERO); 476 if (uvp == NULL) 477 return (NULL); | 455 uvp = malloc(sizeof(struct rsu_vap), M_80211_VAP, M_WAITOK | M_ZERO); |
478 vap = &uvp->vap; 479 480 if (ieee80211_vap_setup(ic, vap, name, unit, opmode, | 456 vap = &uvp->vap; 457 458 if (ieee80211_vap_setup(ic, vap, name, unit, opmode, |
481 flags, bssid, mac) != 0) { | 459 flags, bssid) != 0) { |
482 /* out of memory */ 483 free(uvp, M_80211_VAP); 484 return (NULL); 485 } 486 487 /* override state transition machine */ 488 uvp->newstate = vap->iv_newstate; 489 vap->iv_newstate = rsu_newstate; 490 491 /* complete setup */ 492 ieee80211_vap_attach(vap, ieee80211_media_change, | 460 /* out of memory */ 461 free(uvp, M_80211_VAP); 462 return (NULL); 463 } 464 465 /* override state transition machine */ 466 uvp->newstate = vap->iv_newstate; 467 vap->iv_newstate = rsu_newstate; 468 469 /* complete setup */ 470 ieee80211_vap_attach(vap, ieee80211_media_change, |
493 ieee80211_media_status); | 471 ieee80211_media_status, mac); |
494 ic->ic_opmode = opmode; 495 496 return (vap); 497} 498 499static void 500rsu_vap_delete(struct ieee80211vap *vap) 501{ 502 struct rsu_vap *uvp = RSU_VAP(vap); 503 504 ieee80211_vap_detach(vap); 505 free(uvp, M_80211_VAP); 506} 507 508static void 509rsu_scan_start(struct ieee80211com *ic) 510{ | 472 ic->ic_opmode = opmode; 473 474 return (vap); 475} 476 477static void 478rsu_vap_delete(struct ieee80211vap *vap) 479{ 480 struct rsu_vap *uvp = RSU_VAP(vap); 481 482 ieee80211_vap_detach(vap); 483 free(uvp, M_80211_VAP); 484} 485 486static void 487rsu_scan_start(struct ieee80211com *ic) 488{ |
489 struct rsu_softc *sc = ic->ic_softc; |
|
511 int error; | 490 int error; |
512 struct ifnet *ifp = ic->ic_ifp; 513 struct rsu_softc *sc = ifp->if_softc; | |
514 515 /* Scanning is done by the firmware. */ 516 RSU_LOCK(sc); 517 error = rsu_site_survey(sc, TAILQ_FIRST(&ic->ic_vaps)); 518 RSU_UNLOCK(sc); 519 if (error != 0) 520 device_printf(sc->sc_dev, 521 "could not send site survey command\n"); --- 149 unchanged lines hidden (view full) --- 671static struct rsu_data * 672rsu_getbuf(struct rsu_softc *sc) 673{ 674 struct rsu_data *bf; 675 676 RSU_ASSERT_LOCKED(sc); 677 678 bf = _rsu_getbuf(sc); | 491 492 /* Scanning is done by the firmware. */ 493 RSU_LOCK(sc); 494 error = rsu_site_survey(sc, TAILQ_FIRST(&ic->ic_vaps)); 495 RSU_UNLOCK(sc); 496 if (error != 0) 497 device_printf(sc->sc_dev, 498 "could not send site survey command\n"); --- 149 unchanged lines hidden (view full) --- 648static struct rsu_data * 649rsu_getbuf(struct rsu_softc *sc) 650{ 651 struct rsu_data *bf; 652 653 RSU_ASSERT_LOCKED(sc); 654 655 bf = _rsu_getbuf(sc); |
679 if (bf == NULL) { 680 struct ifnet *ifp = sc->sc_ifp; | 656 if (bf == NULL) |
681 DPRINTF("stop queue\n"); | 657 DPRINTF("stop queue\n"); |
682 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 683 } | |
684 return (bf); 685} 686 687static int 688rsu_write_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf, 689 int len) 690{ 691 usb_device_request_t req; --- 238 unchanged lines hidden (view full) --- 930 RSU_UNLOCK(sc); 931} 932 933static int 934rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 935{ 936 struct rsu_vap *uvp = RSU_VAP(vap); 937 struct ieee80211com *ic = vap->iv_ic; | 658 return (bf); 659} 660 661static int 662rsu_write_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf, 663 int len) 664{ 665 usb_device_request_t req; --- 238 unchanged lines hidden (view full) --- 904 RSU_UNLOCK(sc); 905} 906 907static int 908rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 909{ 910 struct rsu_vap *uvp = RSU_VAP(vap); 911 struct ieee80211com *ic = vap->iv_ic; |
938 struct rsu_softc *sc = ic->ic_ifp->if_softc; | 912 struct rsu_softc *sc = ic->ic_softc; |
939 struct ieee80211_node *ni; 940 struct ieee80211_rateset *rs; 941 enum ieee80211_state ostate; 942 int error, startcal = 0; 943 944 ostate = vap->iv_state; 945 DPRINTF("%s -> %s\n", ieee80211_state_name[ostate], 946 ieee80211_state_name[nstate]); --- 81 unchanged lines hidden (view full) --- 1028 (void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key)); 1029} 1030#endif 1031 1032static int 1033rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap) 1034{ 1035 struct r92s_fw_cmd_sitesurvey cmd; | 913 struct ieee80211_node *ni; 914 struct ieee80211_rateset *rs; 915 enum ieee80211_state ostate; 916 int error, startcal = 0; 917 918 ostate = vap->iv_state; 919 DPRINTF("%s -> %s\n", ieee80211_state_name[ostate], 920 ieee80211_state_name[nstate]); --- 81 unchanged lines hidden (view full) --- 1002 (void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key)); 1003} 1004#endif 1005 1006static int 1007rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap) 1008{ 1009 struct r92s_fw_cmd_sitesurvey cmd; |
1036 struct ifnet *ifp = sc->sc_ifp; 1037 struct ieee80211com *ic = ifp->if_l2com; | 1010 struct ieee80211com *ic = &sc->sc_ic; |
1038 1039 memset(&cmd, 0, sizeof(cmd)); | 1011 1012 memset(&cmd, 0, sizeof(cmd)); |
1040 if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1) | 1013 if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->sc_scan_pass == 1) |
1041 cmd.active = htole32(1); 1042 cmd.limit = htole32(48); | 1014 cmd.active = htole32(1); 1015 cmd.limit = htole32(48); |
1043 if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) { | 1016 if (sc->sc_scan_pass == 1 && vap->iv_des_nssid > 0) { |
1044 /* Do a directed scan for second pass. */ 1045 cmd.ssidlen = htole32(vap->iv_des_ssid[0].len); 1046 memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid, 1047 vap->iv_des_ssid[0].len); 1048 1049 } | 1017 /* Do a directed scan for second pass. */ 1018 cmd.ssidlen = htole32(vap->iv_des_ssid[0].len); 1019 memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid, 1020 vap->iv_des_ssid[0].len); 1021 1022 } |
1050 DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass); | 1023 DPRINTF("sending site survey command, pass=%d\n", sc->sc_scan_pass); |
1051 return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd))); 1052} 1053 1054static int 1055rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni) 1056{ | 1024 return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd))); 1025} 1026 1027static int 1028rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni) 1029{ |
1057 struct ifnet *ifp = sc->sc_ifp; 1058 struct ieee80211com *ic = ifp->if_l2com; | 1030 struct ieee80211com *ic = &sc->sc_ic; |
1059 struct ieee80211vap *vap = ni->ni_vap; 1060 struct ndis_wlan_bssid_ex *bss; 1061 struct ndis_802_11_fixed_ies *fixed; 1062 struct r92s_fw_cmd_auth auth; 1063 uint8_t buf[sizeof(*bss) + 128] __aligned(4); 1064 uint8_t *frm; 1065 uint8_t opmode; 1066 int error; --- 61 unchanged lines hidden (view full) --- 1128 /* Disassociate from our current BSS. */ 1129 DPRINTF("sending disconnect command\n"); 1130 return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero))); 1131} 1132 1133static void 1134rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) 1135{ | 1031 struct ieee80211vap *vap = ni->ni_vap; 1032 struct ndis_wlan_bssid_ex *bss; 1033 struct ndis_802_11_fixed_ies *fixed; 1034 struct r92s_fw_cmd_auth auth; 1035 uint8_t buf[sizeof(*bss) + 128] __aligned(4); 1036 uint8_t *frm; 1037 uint8_t opmode; 1038 int error; --- 61 unchanged lines hidden (view full) --- 1100 /* Disassociate from our current BSS. */ 1101 DPRINTF("sending disconnect command\n"); 1102 return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero))); 1103} 1104 1105static void 1106rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) 1107{ |
1136 struct ifnet *ifp = sc->sc_ifp; 1137 struct ieee80211com *ic = ifp->if_l2com; | 1108 struct ieee80211com *ic = &sc->sc_ic; |
1138 struct ieee80211_frame *wh; 1139 struct ieee80211_channel *c; 1140 struct ndis_wlan_bssid_ex *bss; 1141 struct mbuf *m; 1142 int pktlen; 1143 1144 if (__predict_false(len < sizeof(*bss))) 1145 return; --- 14 unchanged lines hidden (view full) --- 1160 m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); 1161 if (__predict_false(m == NULL)) 1162 return; 1163 wh = mtod(m, struct ieee80211_frame *); 1164 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 1165 IEEE80211_FC0_SUBTYPE_BEACON; 1166 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 1167 USETW(wh->i_dur, 0); | 1109 struct ieee80211_frame *wh; 1110 struct ieee80211_channel *c; 1111 struct ndis_wlan_bssid_ex *bss; 1112 struct mbuf *m; 1113 int pktlen; 1114 1115 if (__predict_false(len < sizeof(*bss))) 1116 return; --- 14 unchanged lines hidden (view full) --- 1131 m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); 1132 if (__predict_false(m == NULL)) 1133 return; 1134 wh = mtod(m, struct ieee80211_frame *); 1135 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 1136 IEEE80211_FC0_SUBTYPE_BEACON; 1137 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 1138 USETW(wh->i_dur, 0); |
1168 IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr); | 1139 IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr); |
1169 IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr); 1170 IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr); 1171 *(uint16_t *)wh->i_seq = 0; 1172 memcpy(&wh[1], (uint8_t *)&bss[1], le32toh(bss->ieslen)); 1173 1174 /* Finalize mbuf. */ 1175 m->m_pkthdr.len = m->m_len = pktlen; | 1140 IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr); 1141 IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr); 1142 *(uint16_t *)wh->i_seq = 0; 1143 memcpy(&wh[1], (uint8_t *)&bss[1], le32toh(bss->ieslen)); 1144 1145 /* Finalize mbuf. */ 1146 m->m_pkthdr.len = m->m_len = pktlen; |
1176 m->m_pkthdr.rcvif = ifp; | |
1177 /* Fix the channel. */ 1178 c = ieee80211_find_channel_byieee(ic, 1179 le32toh(bss->config.dsconfig), 1180 IEEE80211_CHAN_G); 1181 if (c) { 1182 ic->ic_curchan = c; 1183 ieee80211_radiotap_chan_change(ic); 1184 } 1185 /* XXX avoid a LOR */ 1186 RSU_UNLOCK(sc); 1187 ieee80211_input_all(ic, m, le32toh(bss->rssi), 0); 1188 RSU_LOCK(sc); 1189} 1190 1191static void 1192rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) 1193{ | 1147 /* Fix the channel. */ 1148 c = ieee80211_find_channel_byieee(ic, 1149 le32toh(bss->config.dsconfig), 1150 IEEE80211_CHAN_G); 1151 if (c) { 1152 ic->ic_curchan = c; 1153 ieee80211_radiotap_chan_change(ic); 1154 } 1155 /* XXX avoid a LOR */ 1156 RSU_UNLOCK(sc); 1157 ieee80211_input_all(ic, m, le32toh(bss->rssi), 0); 1158 RSU_LOCK(sc); 1159} 1160 1161static void 1162rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) 1163{ |
1194 struct ifnet *ifp = sc->sc_ifp; 1195 struct ieee80211com *ic = ifp->if_l2com; | 1164 struct ieee80211com *ic = &sc->sc_ic; |
1196 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1197 struct ieee80211_node *ni = vap->iv_bss; 1198 struct r92s_event_join_bss *rsp; 1199 uint32_t tmp; 1200 int res; 1201 1202 if (__predict_false(len < sizeof(*rsp))) 1203 return; --- 19 unchanged lines hidden (view full) --- 1223 ieee80211_new_state(vap, IEEE80211_S_RUN, 1224 IEEE80211_FC0_SUBTYPE_ASSOC_RESP); 1225 RSU_LOCK(sc); 1226} 1227 1228static void 1229rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) 1230{ | 1165 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1166 struct ieee80211_node *ni = vap->iv_bss; 1167 struct r92s_event_join_bss *rsp; 1168 uint32_t tmp; 1169 int res; 1170 1171 if (__predict_false(len < sizeof(*rsp))) 1172 return; --- 19 unchanged lines hidden (view full) --- 1192 ieee80211_new_state(vap, IEEE80211_S_RUN, 1193 IEEE80211_FC0_SUBTYPE_ASSOC_RESP); 1194 RSU_LOCK(sc); 1195} 1196 1197static void 1198rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) 1199{ |
1231 struct ifnet *ifp = sc->sc_ifp; 1232 struct ieee80211com *ic = ifp->if_l2com; | 1200 struct ieee80211com *ic = &sc->sc_ic; |
1233 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1234 1235 DPRINTFN(4, "Rx event code=%d len=%d\n", code, len); 1236 switch (code) { 1237 case R92S_EVT_SURVEY: 1238 if (vap->iv_state == IEEE80211_S_SCAN) 1239 rsu_event_survey(sc, buf, len); 1240 break; 1241 case R92S_EVT_SURVEY_DONE: 1242 DPRINTF("site survey pass %d done, found %d BSS\n", | 1201 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 1202 1203 DPRINTFN(4, "Rx event code=%d len=%d\n", code, len); 1204 switch (code) { 1205 case R92S_EVT_SURVEY: 1206 if (vap->iv_state == IEEE80211_S_SCAN) 1207 rsu_event_survey(sc, buf, len); 1208 break; 1209 case R92S_EVT_SURVEY_DONE: 1210 DPRINTF("site survey pass %d done, found %d BSS\n", |
1243 sc->scan_pass, le32toh(*(uint32_t *)buf)); | 1211 sc->sc_scan_pass, le32toh(*(uint32_t *)buf)); |
1244 if (vap->iv_state != IEEE80211_S_SCAN) 1245 break; /* Ignore if not scanning. */ | 1212 if (vap->iv_state != IEEE80211_S_SCAN) 1213 break; /* Ignore if not scanning. */ |
1246 if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) { | 1214 if (sc->sc_scan_pass == 0 && vap->iv_des_nssid != 0) { |
1247 /* Schedule a directed scan for hidden APs. */ | 1215 /* Schedule a directed scan for hidden APs. */ |
1248 sc->scan_pass = 1; | 1216 sc->sc_scan_pass = 1; |
1249 RSU_UNLOCK(sc); 1250 ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); 1251 RSU_LOCK(sc); 1252 break; 1253 } | 1217 RSU_UNLOCK(sc); 1218 ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); 1219 RSU_LOCK(sc); 1220 break; 1221 } |
1254 sc->scan_pass = 0; | 1222 sc->sc_scan_pass = 0; |
1255 break; 1256 case R92S_EVT_JOIN_BSS: 1257 if (vap->iv_state == IEEE80211_S_AUTH) 1258 rsu_event_join_bss(sc, buf, len); 1259 break; 1260#if 0 1261XXX This event is occurring regularly, possibly due to some power saving event 1262XXX and disrupts the WLAN traffic. Disable for now. --- 6 unchanged lines hidden (view full) --- 1269 RSU_LOCK(sc); 1270 } 1271 break; 1272#endif 1273 case R92S_EVT_WPS_PBC: 1274 DPRINTF("WPS PBC pushed.\n"); 1275 break; 1276 case R92S_EVT_FWDBG: | 1223 break; 1224 case R92S_EVT_JOIN_BSS: 1225 if (vap->iv_state == IEEE80211_S_AUTH) 1226 rsu_event_join_bss(sc, buf, len); 1227 break; 1228#if 0 1229XXX This event is occurring regularly, possibly due to some power saving event 1230XXX and disrupts the WLAN traffic. Disable for now. --- 6 unchanged lines hidden (view full) --- 1237 RSU_LOCK(sc); 1238 } 1239 break; 1240#endif 1241 case R92S_EVT_WPS_PBC: 1242 DPRINTF("WPS PBC pushed.\n"); 1243 break; 1244 case R92S_EVT_FWDBG: |
1277 if (ifp->if_flags & IFF_DEBUG) { | 1245 if (vap->iv_ifp->if_flags & IFF_DEBUG) { |
1278 buf[60] = '\0'; 1279 printf("FWDBG: %s\n", (char *)buf); 1280 } 1281 break; 1282 default: 1283 break; 1284 } 1285} --- 50 unchanged lines hidden (view full) --- 1336 rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 106; 1337 } 1338 return (rssi); 1339} 1340 1341static struct mbuf * 1342rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) 1343{ | 1246 buf[60] = '\0'; 1247 printf("FWDBG: %s\n", (char *)buf); 1248 } 1249 break; 1250 default: 1251 break; 1252 } 1253} --- 50 unchanged lines hidden (view full) --- 1304 rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 106; 1305 } 1306 return (rssi); 1307} 1308 1309static struct mbuf * 1310rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) 1311{ |
1344 struct ifnet *ifp = sc->sc_ifp; 1345 struct ieee80211com *ic = ifp->if_l2com; | 1312 struct ieee80211com *ic = &sc->sc_ic; |
1346 struct ieee80211_frame *wh; 1347 struct r92s_rx_stat *stat; 1348 uint32_t rxdw0, rxdw3; 1349 struct mbuf *m; 1350 uint8_t rate; 1351 int infosz; 1352 1353 stat = (struct r92s_rx_stat *)buf; 1354 rxdw0 = le32toh(stat->rxdw0); 1355 rxdw3 = le32toh(stat->rxdw3); 1356 1357 if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) { | 1313 struct ieee80211_frame *wh; 1314 struct r92s_rx_stat *stat; 1315 uint32_t rxdw0, rxdw3; 1316 struct mbuf *m; 1317 uint8_t rate; 1318 int infosz; 1319 1320 stat = (struct r92s_rx_stat *)buf; 1321 rxdw0 = le32toh(stat->rxdw0); 1322 rxdw3 = le32toh(stat->rxdw3); 1323 1324 if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) { |
1358 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | 1325 counter_u64_add(ic->ic_ierrors, 1); |
1359 return NULL; 1360 } 1361 if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) { | 1326 return NULL; 1327 } 1328 if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) { |
1362 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | 1329 counter_u64_add(ic->ic_ierrors, 1); |
1363 return NULL; 1364 } 1365 1366 rate = MS(rxdw3, R92S_RXDW3_RATE); 1367 infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8; 1368 1369 /* Get RSSI from PHY status descriptor if present. */ 1370 if (infosz != 0) 1371 *rssi = rsu_get_rssi(sc, rate, &stat[1]); 1372 else 1373 *rssi = 0; 1374 1375 DPRINTFN(5, "Rx frame len=%d rate=%d infosz=%d rssi=%d\n", 1376 pktlen, rate, infosz, *rssi); 1377 1378 m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); 1379 if (__predict_false(m == NULL)) { | 1330 return NULL; 1331 } 1332 1333 rate = MS(rxdw3, R92S_RXDW3_RATE); 1334 infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8; 1335 1336 /* Get RSSI from PHY status descriptor if present. */ 1337 if (infosz != 0) 1338 *rssi = rsu_get_rssi(sc, rate, &stat[1]); 1339 else 1340 *rssi = 0; 1341 1342 DPRINTFN(5, "Rx frame len=%d rate=%d infosz=%d rssi=%d\n", 1343 pktlen, rate, infosz, *rssi); 1344 1345 m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); 1346 if (__predict_false(m == NULL)) { |
1380 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | 1347 counter_u64_add(ic->ic_ierrors, 1); |
1381 return NULL; 1382 } | 1348 return NULL; 1349 } |
1383 /* Finalize mbuf. */ 1384 m->m_pkthdr.rcvif = ifp; | |
1385 /* Hardware does Rx TCP checksum offload. */ 1386 if (rxdw3 & R92S_RXDW3_TCPCHKVALID) { 1387 if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT)) 1388 m->m_pkthdr.csum_flags |= CSUM_DATA_VALID; 1389 } 1390 wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); 1391 memcpy(mtod(m, uint8_t *), wh, pktlen); 1392 m->m_pkthdr.len = m->m_len = pktlen; --- 81 unchanged lines hidden (view full) --- 1474 1475 return (m0); 1476} 1477 1478static struct mbuf * 1479rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) 1480{ 1481 struct rsu_softc *sc = data->sc; | 1350 /* Hardware does Rx TCP checksum offload. */ 1351 if (rxdw3 & R92S_RXDW3_TCPCHKVALID) { 1352 if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT)) 1353 m->m_pkthdr.csum_flags |= CSUM_DATA_VALID; 1354 } 1355 wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); 1356 memcpy(mtod(m, uint8_t *), wh, pktlen); 1357 m->m_pkthdr.len = m->m_len = pktlen; --- 81 unchanged lines hidden (view full) --- 1439 1440 return (m0); 1441} 1442 1443static struct mbuf * 1444rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) 1445{ 1446 struct rsu_softc *sc = data->sc; |
1447 struct ieee80211com *ic = &sc->sc_ic; |
|
1482 struct r92s_rx_stat *stat; 1483 int len; 1484 1485 usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 1486 1487 if (__predict_false(len < sizeof(*stat))) { 1488 DPRINTF("xfer too short %d\n", len); | 1448 struct r92s_rx_stat *stat; 1449 int len; 1450 1451 usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 1452 1453 if (__predict_false(len < sizeof(*stat))) { 1454 DPRINTF("xfer too short %d\n", len); |
1489 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); | 1455 counter_u64_add(ic->ic_ierrors, 1); |
1490 return (NULL); 1491 } 1492 /* Determine if it is a firmware C2H event or an 802.11 frame. */ 1493 stat = (struct r92s_rx_stat *)data->buf; 1494 if ((le32toh(stat->rxdw1) & 0x1ff) == 0x1ff) { 1495 rsu_rx_multi_event(sc, data->buf, len); 1496 /* No packets to process. */ 1497 return (NULL); 1498 } else 1499 return (rsu_rx_multi_frame(sc, data->buf, len, rssi)); 1500} 1501 1502static void 1503rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) 1504{ 1505 struct rsu_softc *sc = usbd_xfer_softc(xfer); | 1456 return (NULL); 1457 } 1458 /* Determine if it is a firmware C2H event or an 802.11 frame. */ 1459 stat = (struct r92s_rx_stat *)data->buf; 1460 if ((le32toh(stat->rxdw1) & 0x1ff) == 0x1ff) { 1461 rsu_rx_multi_event(sc, data->buf, len); 1462 /* No packets to process. */ 1463 return (NULL); 1464 } else 1465 return (rsu_rx_multi_frame(sc, data->buf, len, rssi)); 1466} 1467 1468static void 1469rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) 1470{ 1471 struct rsu_softc *sc = usbd_xfer_softc(xfer); |
1506 struct ifnet *ifp = sc->sc_ifp; 1507 struct ieee80211com *ic = ifp->if_l2com; | 1472 struct ieee80211com *ic = &sc->sc_ic; |
1508 struct ieee80211_frame *wh; 1509 struct ieee80211_node *ni; 1510 struct mbuf *m = NULL, *next; 1511 struct rsu_data *data; 1512 int rssi = 1; 1513 1514 RSU_ASSERT_LOCKED(sc); 1515 --- 43 unchanged lines hidden (view full) --- 1559 /* needs it to the inactive queue due to a error. */ 1560 data = STAILQ_FIRST(&sc->sc_rx_active); 1561 if (data != NULL) { 1562 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 1563 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 1564 } 1565 if (error != USB_ERR_CANCELLED) { 1566 usbd_xfer_set_stall(xfer); | 1473 struct ieee80211_frame *wh; 1474 struct ieee80211_node *ni; 1475 struct mbuf *m = NULL, *next; 1476 struct rsu_data *data; 1477 int rssi = 1; 1478 1479 RSU_ASSERT_LOCKED(sc); 1480 --- 43 unchanged lines hidden (view full) --- 1524 /* needs it to the inactive queue due to a error. */ 1525 data = STAILQ_FIRST(&sc->sc_rx_active); 1526 if (data != NULL) { 1527 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 1528 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 1529 } 1530 if (error != USB_ERR_CANCELLED) { 1531 usbd_xfer_set_stall(xfer); |
1567 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | 1532 counter_u64_add(ic->ic_ierrors, 1); |
1568 goto tr_setup; 1569 } 1570 break; 1571 } 1572 1573} 1574 | 1533 goto tr_setup; 1534 } 1535 break; 1536 } 1537 1538} 1539 |
1575 | |
1576static void 1577rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data) 1578{ | 1540static void 1541rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data) 1542{ |
1579 struct rsu_softc *sc = usbd_xfer_softc(xfer); 1580 struct ifnet *ifp = sc->sc_ifp; 1581 struct mbuf *m; | |
1582 | 1543 |
1583 RSU_ASSERT_LOCKED(sc); 1584 1585 /* 1586 * Do any tx complete callback. Note this must be done before releasing 1587 * the node reference. 1588 */ | |
1589 if (data->m) { | 1544 if (data->m) { |
1590 m = data->m; 1591 if (m->m_flags & M_TXCB) { 1592 /* XXX status? */ 1593 ieee80211_process_callback(data->ni, m, 0); 1594 } 1595 m_freem(m); | 1545 /* XXX status? */ 1546 ieee80211_tx_complete(data->ni, data->m, 0); |
1596 data->m = NULL; | 1547 data->m = NULL; |
1597 } 1598 if (data->ni) { 1599 ieee80211_free_node(data->ni); | |
1600 data->ni = NULL; 1601 } | 1548 data->ni = NULL; 1549 } |
1602 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 1603 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | |
1604} 1605 1606static void 1607rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error, 1608 uint8_t which) 1609{ 1610 struct rsu_softc *sc = usbd_xfer_softc(xfer); | 1550} 1551 1552static void 1553rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error, 1554 uint8_t which) 1555{ 1556 struct rsu_softc *sc = usbd_xfer_softc(xfer); |
1611 struct ifnet *ifp = sc->sc_ifp; | 1557 struct ieee80211com *ic = &sc->sc_ic; |
1612 struct rsu_data *data; 1613 1614 RSU_ASSERT_LOCKED(sc); 1615 1616 switch (USB_GET_STATE(xfer)) { 1617 case USB_ST_TRANSFERRED: 1618 data = STAILQ_FIRST(&sc->sc_tx_active[which]); 1619 if (data == NULL) --- 18 unchanged lines hidden (view full) --- 1638 break; 1639 default: 1640 data = STAILQ_FIRST(&sc->sc_tx_active[which]); 1641 if (data != NULL) { 1642 STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); 1643 rsu_txeof(xfer, data); 1644 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); 1645 } | 1558 struct rsu_data *data; 1559 1560 RSU_ASSERT_LOCKED(sc); 1561 1562 switch (USB_GET_STATE(xfer)) { 1563 case USB_ST_TRANSFERRED: 1564 data = STAILQ_FIRST(&sc->sc_tx_active[which]); 1565 if (data == NULL) --- 18 unchanged lines hidden (view full) --- 1584 break; 1585 default: 1586 data = STAILQ_FIRST(&sc->sc_tx_active[which]); 1587 if (data != NULL) { 1588 STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); 1589 rsu_txeof(xfer, data); 1590 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); 1591 } |
1646 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | 1592 counter_u64_add(ic->ic_oerrors, 1); |
1647 1648 if (error != USB_ERR_CANCELLED) { 1649 usbd_xfer_set_stall(xfer); 1650 goto tr_setup; 1651 } 1652 break; 1653 } 1654} --- 9 unchanged lines hidden (view full) --- 1664{ 1665 rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO); 1666} 1667 1668static int 1669rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 1670 struct mbuf *m0, struct rsu_data *data) 1671{ | 1593 1594 if (error != USB_ERR_CANCELLED) { 1595 usbd_xfer_set_stall(xfer); 1596 goto tr_setup; 1597 } 1598 break; 1599 } 1600} --- 9 unchanged lines hidden (view full) --- 1610{ 1611 rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO); 1612} 1613 1614static int 1615rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 1616 struct mbuf *m0, struct rsu_data *data) 1617{ |
1672 struct ifnet *ifp = sc->sc_ifp; 1673 struct ieee80211com *ic = ifp->if_l2com; | 1618 struct ieee80211com *ic = &sc->sc_ic; |
1674 struct ieee80211vap *vap = ni->ni_vap; 1675 struct ieee80211_frame *wh; 1676 struct ieee80211_key *k = NULL; 1677 struct r92s_tx_desc *txd; 1678 uint8_t type; 1679 uint8_t tid = 0; 1680 uint8_t which; 1681 int hasqos; --- 85 unchanged lines hidden (view full) --- 1767 data->m = m0; 1768 STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next); 1769 1770 /* start transfer, if any */ 1771 usbd_transfer_start(sc->sc_xfer[which]); 1772 return (0); 1773} 1774 | 1619 struct ieee80211vap *vap = ni->ni_vap; 1620 struct ieee80211_frame *wh; 1621 struct ieee80211_key *k = NULL; 1622 struct r92s_tx_desc *txd; 1623 uint8_t type; 1624 uint8_t tid = 0; 1625 uint8_t which; 1626 int hasqos; --- 85 unchanged lines hidden (view full) --- 1712 data->m = m0; 1713 STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next); 1714 1715 /* start transfer, if any */ 1716 usbd_transfer_start(sc->sc_xfer[which]); 1717 return (0); 1718} 1719 |
1775static void 1776rsu_start(struct ifnet *ifp) | 1720static int 1721rsu_transmit(struct ieee80211com *ic, struct mbuf *m) |
1777{ | 1722{ |
1778 struct rsu_softc *sc = ifp->if_softc; | 1723 struct rsu_softc *sc = ic->ic_softc; 1724 int error; |
1779 | 1725 |
1780 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 1781 return; 1782 | |
1783 RSU_LOCK(sc); | 1726 RSU_LOCK(sc); |
1784 rsu_start_locked(ifp); | 1727 if (!sc->sc_running) { 1728 RSU_UNLOCK(sc); 1729 return (ENXIO); 1730 } 1731 error = mbufq_enqueue(&sc->sc_snd, m); 1732 if (error) { 1733 RSU_UNLOCK(sc); 1734 return (error); 1735 } 1736 rsu_start(sc); |
1785 RSU_UNLOCK(sc); | 1737 RSU_UNLOCK(sc); |
1738 1739 return (0); |
|
1786} 1787 1788static void | 1740} 1741 1742static void |
1789rsu_start_locked(struct ifnet *ifp) | 1743rsu_start(struct rsu_softc *sc) |
1790{ | 1744{ |
1791 struct rsu_softc *sc = ifp->if_softc; | |
1792 struct ieee80211_node *ni; 1793 struct rsu_data *bf; 1794 struct mbuf *m; 1795 1796 RSU_ASSERT_LOCKED(sc); 1797 | 1745 struct ieee80211_node *ni; 1746 struct rsu_data *bf; 1747 struct mbuf *m; 1748 1749 RSU_ASSERT_LOCKED(sc); 1750 |
1798 for (;;) { 1799 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1800 if (m == NULL) | 1751 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 1752 bf = rsu_getbuf(sc); 1753 if (bf == NULL) { 1754 mbufq_prepend(&sc->sc_snd, m); |
1801 break; | 1755 break; |
1756 } 1757 |
|
1802 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 1803 m->m_pkthdr.rcvif = NULL; 1804 | 1758 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 1759 m->m_pkthdr.rcvif = NULL; 1760 |
1805 bf = rsu_getbuf(sc); 1806 if (bf == NULL) { 1807 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); 1808 m_freem(m); 1809 ieee80211_free_node(ni); 1810 } else if (rsu_tx_start(sc, ni, m, bf) != 0) { 1811 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | 1761 if (rsu_tx_start(sc, ni, m, bf) != 0) { 1762 if_inc_counter(ni->ni_vap->iv_ifp, 1763 IFCOUNTER_OERRORS, 1); |
1812 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); 1813 ieee80211_free_node(ni); | 1764 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); 1765 ieee80211_free_node(ni); |
1766 break; |
|
1814 } 1815 } 1816} 1817 | 1767 } 1768 } 1769} 1770 |
1818static int 1819rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | 1771static void 1772rsu_parent(struct ieee80211com *ic) |
1820{ | 1773{ |
1821 struct ieee80211com *ic = ifp->if_l2com; 1822 struct ifreq *ifr = (struct ifreq *) data; 1823 int error = 0, startall = 0; | 1774 struct rsu_softc *sc = ic->ic_softc; 1775 int startall = 0; |
1824 | 1776 |
1825 switch (cmd) { 1826 case SIOCSIFFLAGS: 1827 if (ifp->if_flags & IFF_UP) { 1828 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1829 rsu_init(ifp->if_softc); 1830 startall = 1; 1831 } 1832 } else { 1833 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1834 rsu_stop(ifp, 1); | 1777 RSU_LOCK(sc); 1778 if (ic->ic_nrunning > 0) { 1779 if (!sc->sc_running) { 1780 rsu_init(sc); 1781 startall = 1; |
1835 } | 1782 } |
1836 if (startall) 1837 ieee80211_start_all(ic); 1838 break; 1839 case SIOCGIFMEDIA: 1840 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1841 break; 1842 case SIOCGIFADDR: 1843 error = ether_ioctl(ifp, cmd, data); 1844 break; 1845 default: 1846 error = EINVAL; 1847 break; 1848 } | 1783 } else if (sc->sc_running) 1784 rsu_stop(sc); 1785 RSU_UNLOCK(sc); |
1849 | 1786 |
1850 return (error); | 1787 if (startall) 1788 ieee80211_start_all(ic); |
1851} 1852 1853/* 1854 * Power on sequence for A-cut adapters. 1855 */ 1856static void 1857rsu_power_on_acut(struct rsu_softc *sc) 1858{ --- 432 unchanged lines hidden (view full) --- 2291} 2292 2293 2294static int 2295rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2296 const struct ieee80211_bpf_params *params) 2297{ 2298 struct ieee80211com *ic = ni->ni_ic; | 1789} 1790 1791/* 1792 * Power on sequence for A-cut adapters. 1793 */ 1794static void 1795rsu_power_on_acut(struct rsu_softc *sc) 1796{ --- 432 unchanged lines hidden (view full) --- 2229} 2230 2231 2232static int 2233rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 2234 const struct ieee80211_bpf_params *params) 2235{ 2236 struct ieee80211com *ic = ni->ni_ic; |
2299 struct ifnet *ifp = ic->ic_ifp; 2300 struct rsu_softc *sc = ifp->if_softc; | 2237 struct rsu_softc *sc = ic->ic_softc; |
2301 struct rsu_data *bf; 2302 2303 /* prevent management frames from being sent if we're not ready */ | 2238 struct rsu_data *bf; 2239 2240 /* prevent management frames from being sent if we're not ready */ |
2304 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { | 2241 if (!sc->sc_running) { |
2305 m_freem(m); 2306 ieee80211_free_node(ni); 2307 return (ENETDOWN); 2308 } 2309 RSU_LOCK(sc); 2310 bf = rsu_getbuf(sc); 2311 if (bf == NULL) { 2312 ieee80211_free_node(ni); 2313 m_freem(m); 2314 RSU_UNLOCK(sc); 2315 return (ENOBUFS); 2316 } | 2242 m_freem(m); 2243 ieee80211_free_node(ni); 2244 return (ENETDOWN); 2245 } 2246 RSU_LOCK(sc); 2247 bf = rsu_getbuf(sc); 2248 if (bf == NULL) { 2249 ieee80211_free_node(ni); 2250 m_freem(m); 2251 RSU_UNLOCK(sc); 2252 return (ENOBUFS); 2253 } |
2317 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | |
2318 if (rsu_tx_start(sc, ni, m, bf) != 0) { 2319 ieee80211_free_node(ni); | 2254 if (rsu_tx_start(sc, ni, m, bf) != 0) { 2255 ieee80211_free_node(ni); |
2320 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |
2321 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); 2322 RSU_UNLOCK(sc); 2323 return (EIO); 2324 } 2325 RSU_UNLOCK(sc); 2326 2327 return (0); 2328} 2329 2330static void | 2256 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); 2257 RSU_UNLOCK(sc); 2258 return (EIO); 2259 } 2260 RSU_UNLOCK(sc); 2261 2262 return (0); 2263} 2264 2265static void |
2331rsu_init(void *arg) | 2266rsu_init(struct rsu_softc *sc) |
2332{ | 2267{ |
2333 struct rsu_softc *sc = arg; 2334 2335 RSU_LOCK(sc); 2336 rsu_init_locked(arg); 2337 RSU_UNLOCK(sc); 2338} 2339 2340static void 2341rsu_init_locked(struct rsu_softc *sc) 2342{ 2343 struct ifnet *ifp = sc->sc_ifp; | 2268 struct ieee80211com *ic = &sc->sc_ic; 2269 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 2270 uint8_t macaddr[IEEE80211_ADDR_LEN]; |
2344 struct r92s_set_pwr_mode cmd; 2345 int error; 2346 int i; 2347 | 2271 struct r92s_set_pwr_mode cmd; 2272 int error; 2273 int i; 2274 |
2275 RSU_ASSERT_LOCKED(sc); 2276 |
|
2348 /* Init host async commands ring. */ 2349 sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; 2350 2351 /* Power on adapter. */ 2352 if (sc->cut == 1) 2353 rsu_power_on_acut(sc); 2354 else 2355 rsu_power_on_bcut(sc); --- 23 unchanged lines hidden (view full) --- 2379 rsu_write_1(sc, 0x00d9, 0x01); 2380 /* Set USB Rx aggregation timeout (1.7ms/4). */ 2381 rsu_write_1(sc, 0xfe5b, 0x04); 2382 /* Fix USB Rx FIFO issue. */ 2383 rsu_write_1(sc, 0xfe5c, 2384 rsu_read_1(sc, 0xfe5c) | 0x80); 2385 2386 /* Set MAC address. */ | 2277 /* Init host async commands ring. */ 2278 sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; 2279 2280 /* Power on adapter. */ 2281 if (sc->cut == 1) 2282 rsu_power_on_acut(sc); 2283 else 2284 rsu_power_on_bcut(sc); --- 23 unchanged lines hidden (view full) --- 2308 rsu_write_1(sc, 0x00d9, 0x01); 2309 /* Set USB Rx aggregation timeout (1.7ms/4). */ 2310 rsu_write_1(sc, 0xfe5b, 0x04); 2311 /* Fix USB Rx FIFO issue. */ 2312 rsu_write_1(sc, 0xfe5c, 2313 rsu_read_1(sc, 0xfe5c) | 0x80); 2314 2315 /* Set MAC address. */ |
2387 rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp), 2388 IEEE80211_ADDR_LEN); | 2316 IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr); 2317 rsu_write_region_1(sc, R92S_MACID, macaddr, IEEE80211_ADDR_LEN); |
2389 2390 /* It really takes 1.5 seconds for the firmware to boot: */ 2391 usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2); 2392 | 2318 2319 /* It really takes 1.5 seconds for the firmware to boot: */ 2320 usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2); 2321 |
2393 DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp))); 2394 error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp), | 2322 DPRINTF("setting MAC address to %s\n", ether_sprintf(macaddr)); 2323 error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, macaddr, |
2395 IEEE80211_ADDR_LEN); 2396 if (error != 0) { 2397 device_printf(sc->sc_dev, "could not set MAC address\n"); 2398 goto fail; 2399 } 2400 2401 rsu_write_1(sc, R92S_USB_HRPWM, 2402 R92S_USB_HRPWM_PS_ST_ACTIVE | R92S_USB_HRPWM_PS_ALL_ON); --- 19 unchanged lines hidden (view full) --- 2422 "could not enable 40MHz mode\n"); 2423 goto fail; 2424 } 2425 } 2426 2427 /* Set default channel. */ 2428 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2429#endif | 2324 IEEE80211_ADDR_LEN); 2325 if (error != 0) { 2326 device_printf(sc->sc_dev, "could not set MAC address\n"); 2327 goto fail; 2328 } 2329 2330 rsu_write_1(sc, R92S_USB_HRPWM, 2331 R92S_USB_HRPWM_PS_ST_ACTIVE | R92S_USB_HRPWM_PS_ALL_ON); --- 19 unchanged lines hidden (view full) --- 2351 "could not enable 40MHz mode\n"); 2352 goto fail; 2353 } 2354 } 2355 2356 /* Set default channel. */ 2357 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2358#endif |
2430 sc->scan_pass = 0; | 2359 sc->sc_scan_pass = 0; |
2431 usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); 2432 2433 /* We're ready to go. */ | 2360 usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); 2361 2362 /* We're ready to go. */ |
2434 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 2435 ifp->if_drv_flags |= IFF_DRV_RUNNING; | 2363 sc->sc_running = 1; |
2436 return; 2437fail: 2438 /* Need to stop all failed transfers, if any */ 2439 for (i = 0; i != RSU_N_TRANSFER; i++) 2440 usbd_transfer_stop(sc->sc_xfer[i]); 2441} 2442 2443static void | 2364 return; 2365fail: 2366 /* Need to stop all failed transfers, if any */ 2367 for (i = 0; i != RSU_N_TRANSFER; i++) 2368 usbd_transfer_stop(sc->sc_xfer[i]); 2369} 2370 2371static void |
2444rsu_stop(struct ifnet *ifp, int disable) | 2372rsu_stop(struct rsu_softc *sc) |
2445{ | 2373{ |
2446 struct rsu_softc *sc = ifp->if_softc; 2447 2448 RSU_LOCK(sc); 2449 rsu_stop_locked(ifp, disable); 2450 RSU_UNLOCK(sc); 2451} 2452 2453static void 2454rsu_stop_locked(struct ifnet *ifp, int disable __unused) 2455{ 2456 struct rsu_softc *sc = ifp->if_softc; | |
2457 int i; 2458 | 2374 int i; 2375 |
2459 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); | 2376 sc->sc_running = 0; |
2460 sc->sc_calibrating = 0; 2461 taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL); 2462 2463 /* Power off adapter. */ 2464 rsu_power_off(sc); 2465 2466 for (i = 0; i < RSU_N_TRANSFER; i++) 2467 usbd_transfer_stop(sc->sc_xfer[i]); 2468} 2469 2470static void 2471rsu_ms_delay(struct rsu_softc *sc) 2472{ 2473 usb_pause_mtx(&sc->sc_mtx, hz / 1000); 2474} | 2377 sc->sc_calibrating = 0; 2378 taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL); 2379 2380 /* Power off adapter. */ 2381 rsu_power_off(sc); 2382 2383 for (i = 0; i < RSU_N_TRANSFER; i++) 2384 usbd_transfer_stop(sc->sc_xfer[i]); 2385} 2386 2387static void 2388rsu_ms_delay(struct rsu_softc *sc) 2389{ 2390 usb_pause_mtx(&sc->sc_mtx, hz / 1000); 2391} |