Deleted Added
full compact
if_rsu.c (286950) if_rsu.c (287197)
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 286950 2015-08-20 05:13:54Z adrian $");
19__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rsu.c 287197 2015-08-27 08:56:39Z 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{
511 int error;
512 struct rsu_softc *sc = ic->ic_softc;
489 struct rsu_softc *sc = ic->ic_softc;
490 int error;
513
514 /* Scanning is done by the firmware. */
515 RSU_LOCK(sc);
516 error = rsu_site_survey(sc, TAILQ_FIRST(&ic->ic_vaps));
517 RSU_UNLOCK(sc);
518 if (error != 0)
519 device_printf(sc->sc_dev,
520 "could not send site survey command\n");

--- 149 unchanged lines hidden (view full) ---

670static struct rsu_data *
671rsu_getbuf(struct rsu_softc *sc)
672{
673 struct rsu_data *bf;
674
675 RSU_ASSERT_LOCKED(sc);
676
677 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);
678 if (bf == NULL) {
679 struct ifnet *ifp = sc->sc_ifp;
656 if (bf == NULL)
680 DPRINTF("stop queue\n");
657 DPRINTF("stop queue\n");
681 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
682 }
683 return (bf);
684}
685
686static int
687rsu_write_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf,
688 int len)
689{
690 usb_device_request_t req;

--- 336 unchanged lines hidden (view full) ---

1027 (void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key));
1028}
1029#endif
1030
1031static int
1032rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap)
1033{
1034 struct r92s_fw_cmd_sitesurvey cmd;
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;

--- 336 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;
1035 struct ifnet *ifp = sc->sc_ifp;
1036 struct ieee80211com *ic = ifp->if_l2com;
1010 struct ieee80211com *ic = &sc->sc_ic;
1037
1038 memset(&cmd, 0, sizeof(cmd));
1011
1012 memset(&cmd, 0, sizeof(cmd));
1039 if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1)
1013 if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->sc_scan_pass == 1)
1040 cmd.active = htole32(1);
1041 cmd.limit = htole32(48);
1014 cmd.active = htole32(1);
1015 cmd.limit = htole32(48);
1042 if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) {
1016 if (sc->sc_scan_pass == 1 && vap->iv_des_nssid > 0) {
1043 /* Do a directed scan for second pass. */
1044 cmd.ssidlen = htole32(vap->iv_des_ssid[0].len);
1045 memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid,
1046 vap->iv_des_ssid[0].len);
1047
1048 }
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 }
1049 DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass);
1023 DPRINTF("sending site survey command, pass=%d\n", sc->sc_scan_pass);
1050 return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd)));
1051}
1052
1053static int
1054rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni)
1055{
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{
1056 struct ifnet *ifp = sc->sc_ifp;
1057 struct ieee80211com *ic = ifp->if_l2com;
1030 struct ieee80211com *ic = &sc->sc_ic;
1058 struct ieee80211vap *vap = ni->ni_vap;
1059 struct ndis_wlan_bssid_ex *bss;
1060 struct ndis_802_11_fixed_ies *fixed;
1061 struct r92s_fw_cmd_auth auth;
1062 uint8_t buf[sizeof(*bss) + 128] __aligned(4);
1063 uint8_t *frm;
1064 uint8_t opmode;
1065 int error;

--- 61 unchanged lines hidden (view full) ---

1127 /* Disassociate from our current BSS. */
1128 DPRINTF("sending disconnect command\n");
1129 return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero)));
1130}
1131
1132static void
1133rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
1134{
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{
1135 struct ifnet *ifp = sc->sc_ifp;
1136 struct ieee80211com *ic = ifp->if_l2com;
1108 struct ieee80211com *ic = &sc->sc_ic;
1137 struct ieee80211_frame *wh;
1138 struct ieee80211_channel *c;
1139 struct ndis_wlan_bssid_ex *bss;
1140 struct mbuf *m;
1141 int pktlen;
1142
1143 if (__predict_false(len < sizeof(*bss)))
1144 return;

--- 14 unchanged lines hidden (view full) ---

1159 m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR);
1160 if (__predict_false(m == NULL))
1161 return;
1162 wh = mtod(m, struct ieee80211_frame *);
1163 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
1164 IEEE80211_FC0_SUBTYPE_BEACON;
1165 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
1166 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);
1167 IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
1139 IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
1168 IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr);
1169 IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr);
1170 *(uint16_t *)wh->i_seq = 0;
1171 memcpy(&wh[1], (uint8_t *)&bss[1], le32toh(bss->ieslen));
1172
1173 /* Finalize mbuf. */
1174 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;
1175 m->m_pkthdr.rcvif = ifp;
1176 /* Fix the channel. */
1177 c = ieee80211_find_channel_byieee(ic,
1178 le32toh(bss->config.dsconfig),
1179 IEEE80211_CHAN_G);
1180 if (c) {
1181 ic->ic_curchan = c;
1182 ieee80211_radiotap_chan_change(ic);
1183 }
1184 /* XXX avoid a LOR */
1185 RSU_UNLOCK(sc);
1186 ieee80211_input_all(ic, m, le32toh(bss->rssi), 0);
1187 RSU_LOCK(sc);
1188}
1189
1190static void
1191rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
1192{
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{
1193 struct ifnet *ifp = sc->sc_ifp;
1194 struct ieee80211com *ic = ifp->if_l2com;
1164 struct ieee80211com *ic = &sc->sc_ic;
1195 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1196 struct ieee80211_node *ni = vap->iv_bss;
1197 struct r92s_event_join_bss *rsp;
1198 uint32_t tmp;
1199 int res;
1200
1201 if (__predict_false(len < sizeof(*rsp)))
1202 return;

--- 19 unchanged lines hidden (view full) ---

1222 ieee80211_new_state(vap, IEEE80211_S_RUN,
1223 IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
1224 RSU_LOCK(sc);
1225}
1226
1227static void
1228rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
1229{
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{
1230 struct ifnet *ifp = sc->sc_ifp;
1231 struct ieee80211com *ic = ifp->if_l2com;
1200 struct ieee80211com *ic = &sc->sc_ic;
1232 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1233
1234 DPRINTFN(4, "Rx event code=%d len=%d\n", code, len);
1235 switch (code) {
1236 case R92S_EVT_SURVEY:
1237 if (vap->iv_state == IEEE80211_S_SCAN)
1238 rsu_event_survey(sc, buf, len);
1239 break;
1240 case R92S_EVT_SURVEY_DONE:
1241 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",
1242 sc->scan_pass, le32toh(*(uint32_t *)buf));
1211 sc->sc_scan_pass, le32toh(*(uint32_t *)buf));
1243 if (vap->iv_state != IEEE80211_S_SCAN)
1244 break; /* Ignore if not scanning. */
1212 if (vap->iv_state != IEEE80211_S_SCAN)
1213 break; /* Ignore if not scanning. */
1245 if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) {
1214 if (sc->sc_scan_pass == 0 && vap->iv_des_nssid != 0) {
1246 /* Schedule a directed scan for hidden APs. */
1215 /* Schedule a directed scan for hidden APs. */
1247 sc->scan_pass = 1;
1216 sc->sc_scan_pass = 1;
1248 RSU_UNLOCK(sc);
1249 ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
1250 RSU_LOCK(sc);
1251 break;
1252 }
1217 RSU_UNLOCK(sc);
1218 ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
1219 RSU_LOCK(sc);
1220 break;
1221 }
1253 sc->scan_pass = 0;
1222 sc->sc_scan_pass = 0;
1254 break;
1255 case R92S_EVT_JOIN_BSS:
1256 if (vap->iv_state == IEEE80211_S_AUTH)
1257 rsu_event_join_bss(sc, buf, len);
1258 break;
1259#if 0
1260XXX This event is occurring regularly, possibly due to some power saving event
1261XXX and disrupts the WLAN traffic. Disable for now.

--- 6 unchanged lines hidden (view full) ---

1268 RSU_LOCK(sc);
1269 }
1270 break;
1271#endif
1272 case R92S_EVT_WPS_PBC:
1273 DPRINTF("WPS PBC pushed.\n");
1274 break;
1275 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:
1276 if (ifp->if_flags & IFF_DEBUG) {
1245 if (vap->iv_ifp->if_flags & IFF_DEBUG) {
1277 buf[60] = '\0';
1278 printf("FWDBG: %s\n", (char *)buf);
1279 }
1280 break;
1281 default:
1282 break;
1283 }
1284}

--- 50 unchanged lines hidden (view full) ---

1335 rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 106;
1336 }
1337 return (rssi);
1338}
1339
1340static struct mbuf *
1341rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
1342{
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{
1343 struct ifnet *ifp = sc->sc_ifp;
1344 struct ieee80211com *ic = ifp->if_l2com;
1312 struct ieee80211com *ic = &sc->sc_ic;
1345 struct ieee80211_frame *wh;
1346 struct r92s_rx_stat *stat;
1347 uint32_t rxdw0, rxdw3;
1348 struct mbuf *m;
1349 uint8_t rate;
1350 int infosz;
1351
1352 stat = (struct r92s_rx_stat *)buf;
1353 rxdw0 = le32toh(stat->rxdw0);
1354 rxdw3 = le32toh(stat->rxdw3);
1355
1356 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)) {
1357 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1325 counter_u64_add(ic->ic_ierrors, 1);
1358 return NULL;
1359 }
1360 if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
1326 return NULL;
1327 }
1328 if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
1361 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1329 counter_u64_add(ic->ic_ierrors, 1);
1362 return NULL;
1363 }
1364
1365 rate = MS(rxdw3, R92S_RXDW3_RATE);
1366 infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8;
1367
1368 /* Get RSSI from PHY status descriptor if present. */
1369 if (infosz != 0)
1370 *rssi = rsu_get_rssi(sc, rate, &stat[1]);
1371 else
1372 *rssi = 0;
1373
1374 DPRINTFN(5, "Rx frame len=%d rate=%d infosz=%d rssi=%d\n",
1375 pktlen, rate, infosz, *rssi);
1376
1377 m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR);
1378 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)) {
1379 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1347 counter_u64_add(ic->ic_ierrors, 1);
1380 return NULL;
1381 }
1348 return NULL;
1349 }
1382 /* Finalize mbuf. */
1383 m->m_pkthdr.rcvif = ifp;
1384 /* Hardware does Rx TCP checksum offload. */
1385 if (rxdw3 & R92S_RXDW3_TCPCHKVALID) {
1386 if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT))
1387 m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
1388 }
1389 wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
1390 memcpy(mtod(m, uint8_t *), wh, pktlen);
1391 m->m_pkthdr.len = m->m_len = pktlen;

--- 81 unchanged lines hidden (view full) ---

1473
1474 return (m0);
1475}
1476
1477static struct mbuf *
1478rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
1479{
1480 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;
1481 struct r92s_rx_stat *stat;
1482 int len;
1483
1484 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
1485
1486 if (__predict_false(len < sizeof(*stat))) {
1487 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);
1488 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1);
1455 counter_u64_add(ic->ic_ierrors, 1);
1489 return (NULL);
1490 }
1491 /* Determine if it is a firmware C2H event or an 802.11 frame. */
1492 stat = (struct r92s_rx_stat *)data->buf;
1493 if ((le32toh(stat->rxdw1) & 0x1ff) == 0x1ff) {
1494 rsu_rx_multi_event(sc, data->buf, len);
1495 /* No packets to process. */
1496 return (NULL);
1497 } else
1498 return (rsu_rx_multi_frame(sc, data->buf, len, rssi));
1499}
1500
1501static void
1502rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
1503{
1504 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);
1505 struct ifnet *ifp = sc->sc_ifp;
1506 struct ieee80211com *ic = ifp->if_l2com;
1472 struct ieee80211com *ic = &sc->sc_ic;
1507 struct ieee80211_frame *wh;
1508 struct ieee80211_node *ni;
1509 struct mbuf *m = NULL, *next;
1510 struct rsu_data *data;
1511 int rssi = 1;
1512
1513 RSU_ASSERT_LOCKED(sc);
1514

--- 43 unchanged lines hidden (view full) ---

1558 /* needs it to the inactive queue due to a error. */
1559 data = STAILQ_FIRST(&sc->sc_rx_active);
1560 if (data != NULL) {
1561 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
1562 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
1563 }
1564 if (error != USB_ERR_CANCELLED) {
1565 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);
1566 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
1532 counter_u64_add(ic->ic_ierrors, 1);
1567 goto tr_setup;
1568 }
1569 break;
1570 }
1571
1572}
1573
1533 goto tr_setup;
1534 }
1535 break;
1536 }
1537
1538}
1539
1574
1575static void
1576rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data)
1577{
1540static void
1541rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data)
1542{
1578 struct rsu_softc *sc = usbd_xfer_softc(xfer);
1579 struct ifnet *ifp = sc->sc_ifp;
1580 struct mbuf *m;
1581
1543
1582 RSU_ASSERT_LOCKED(sc);
1583
1584 /*
1585 * Do any tx complete callback. Note this must be done before releasing
1586 * the node reference.
1587 */
1588 if (data->m) {
1544 if (data->m) {
1589 m = data->m;
1590 if (m->m_flags & M_TXCB) {
1591 /* XXX status? */
1592 ieee80211_process_callback(data->ni, m, 0);
1593 }
1594 m_freem(m);
1545 /* XXX status? */
1546 ieee80211_tx_complete(data->ni, data->m, 0);
1595 data->m = NULL;
1547 data->m = NULL;
1596 }
1597 if (data->ni) {
1598 ieee80211_free_node(data->ni);
1599 data->ni = NULL;
1600 }
1548 data->ni = NULL;
1549 }
1601 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1602 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1603}
1604
1605static void
1606rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error,
1607 uint8_t which)
1608{
1609 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);
1610 struct ifnet *ifp = sc->sc_ifp;
1557 struct ieee80211com *ic = &sc->sc_ic;
1611 struct rsu_data *data;
1612
1613 RSU_ASSERT_LOCKED(sc);
1614
1615 switch (USB_GET_STATE(xfer)) {
1616 case USB_ST_TRANSFERRED:
1617 data = STAILQ_FIRST(&sc->sc_tx_active[which]);
1618 if (data == NULL)

--- 18 unchanged lines hidden (view full) ---

1637 break;
1638 default:
1639 data = STAILQ_FIRST(&sc->sc_tx_active[which]);
1640 if (data != NULL) {
1641 STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
1642 rsu_txeof(xfer, data);
1643 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
1644 }
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 }
1645 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
1592 counter_u64_add(ic->ic_oerrors, 1);
1646
1647 if (error != USB_ERR_CANCELLED) {
1648 usbd_xfer_set_stall(xfer);
1649 goto tr_setup;
1650 }
1651 break;
1652 }
1653}

--- 9 unchanged lines hidden (view full) ---

1663{
1664 rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO);
1665}
1666
1667static int
1668rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
1669 struct mbuf *m0, struct rsu_data *data)
1670{
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{
1671 struct ifnet *ifp = sc->sc_ifp;
1672 struct ieee80211com *ic = ifp->if_l2com;
1618 struct ieee80211com *ic = &sc->sc_ic;
1673 struct ieee80211vap *vap = ni->ni_vap;
1674 struct ieee80211_frame *wh;
1675 struct ieee80211_key *k = NULL;
1676 struct r92s_tx_desc *txd;
1677 uint8_t type;
1678 uint8_t tid = 0;
1679 uint8_t which;
1680 int hasqos;

--- 85 unchanged lines hidden (view full) ---

1766 data->m = m0;
1767 STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
1768
1769 /* start transfer, if any */
1770 usbd_transfer_start(sc->sc_xfer[which]);
1771 return (0);
1772}
1773
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
1774static void
1775rsu_start(struct ifnet *ifp)
1720static int
1721rsu_transmit(struct ieee80211com *ic, struct mbuf *m)
1776{
1722{
1777 struct rsu_softc *sc = ifp->if_softc;
1723 struct rsu_softc *sc = ic->ic_softc;
1724 int error;
1778
1725
1779 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1780 return;
1781
1782 RSU_LOCK(sc);
1726 RSU_LOCK(sc);
1783 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);
1784 RSU_UNLOCK(sc);
1737 RSU_UNLOCK(sc);
1738
1739 return (0);
1785}
1786
1787static void
1740}
1741
1742static void
1788rsu_start_locked(struct ifnet *ifp)
1743rsu_start(struct rsu_softc *sc)
1789{
1744{
1790 struct rsu_softc *sc = ifp->if_softc;
1791 struct ieee80211_node *ni;
1792 struct rsu_data *bf;
1793 struct mbuf *m;
1794
1795 RSU_ASSERT_LOCKED(sc);
1796
1745 struct ieee80211_node *ni;
1746 struct rsu_data *bf;
1747 struct mbuf *m;
1748
1749 RSU_ASSERT_LOCKED(sc);
1750
1797 for (;;) {
1798 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1799 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);
1800 break;
1755 break;
1756 }
1757
1801 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1802 m->m_pkthdr.rcvif = NULL;
1803
1758 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1759 m->m_pkthdr.rcvif = NULL;
1760
1804 bf = rsu_getbuf(sc);
1805 if (bf == NULL) {
1806 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
1807 m_freem(m);
1808 ieee80211_free_node(ni);
1809 } else if (rsu_tx_start(sc, ni, m, bf) != 0) {
1810 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);
1811 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1812 ieee80211_free_node(ni);
1764 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1765 ieee80211_free_node(ni);
1766 break;
1813 }
1814 }
1815}
1816
1767 }
1768 }
1769}
1770
1817static int
1818rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1771static void
1772rsu_parent(struct ieee80211com *ic)
1819{
1773{
1820 struct ieee80211com *ic = ifp->if_l2com;
1821 struct rsu_softc *sc = ic->ic_softc;
1774 struct rsu_softc *sc = ic->ic_softc;
1822 struct ifreq *ifr = (struct ifreq *) data;
1823 int error = 0, startall = 0;
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(sc);
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 = ic->ic_softc;
2301 struct rsu_data *bf;
2302
2303 /* prevent management frames from being sent if we're not ready */
2237 struct rsu_softc *sc = ic->ic_softc;
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}