diff options
Diffstat (limited to 'sys/dev/usb/wlan/if_rsu.c')
-rw-r--r-- | sys/dev/usb/wlan/if_rsu.c | 299 |
1 files changed, 108 insertions, 191 deletions
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index 89b8c00..463a9bd 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -187,15 +187,13 @@ static struct mbuf * static void rsu_txeof(struct usb_xfer *, struct rsu_data *); static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void rsu_init(void *); -static void rsu_init_locked(struct rsu_softc *); +static void rsu_init(struct rsu_softc *); static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, struct mbuf *, struct rsu_data *); -static void rsu_start(struct ifnet *); -static void rsu_start_locked(struct ifnet *); -static int rsu_ioctl(struct ifnet *, u_long, caddr_t); -static void rsu_stop(struct ifnet *, int); -static void rsu_stop_locked(struct ifnet *, int); +static int rsu_transmit(struct ieee80211com *, struct mbuf *); +static void rsu_start(struct rsu_softc *); +static void rsu_parent(struct ieee80211com *); +static void rsu_stop(struct rsu_softc *); static void rsu_ms_delay(struct rsu_softc *); static device_method_t rsu_methods[] = { @@ -285,8 +283,7 @@ rsu_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct rsu_softc *sc = device_get_softc(self); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; int error; uint8_t iface_index, bands; @@ -298,6 +295,7 @@ rsu_attach(device_t self) MTX_DEF); TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, rsu_calib_task, sc); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* Allocate Tx/Rx buffers. */ error = rsu_alloc_rx_list(sc); @@ -333,28 +331,9 @@ rsu_attach(device_t self) device_printf(self, "could not read ROM\n"); goto fail_rom; } - IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]); + IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->rom[0x12]); device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(self, "cannot allocate interface\n"); - goto fail_ifalloc; - } - ic = ifp->if_l2com; - ifp->if_softc = sc; - if_initname(ifp, "rsu", device_get_unit(self)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rsu_init; - ifp->if_ioctl = rsu_ioctl; - ifp->if_start = rsu_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - ifp->if_capabilities |= IFCAP_RXCSUM; - ifp->if_capenable |= IFCAP_RXCSUM; - ifp->if_hwassist = CSUM_TCP; - - ic->ic_ifp = ifp; + ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */ @@ -387,7 +366,7 @@ rsu_attach(device_t self) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_raw_xmit = rsu_raw_xmit; ic->ic_scan_start = rsu_scan_start; ic->ic_scan_end = rsu_scan_end; @@ -395,6 +374,8 @@ rsu_attach(device_t self) ic->ic_vap_create = rsu_vap_create; ic->ic_vap_delete = rsu_vap_delete; ic->ic_update_mcast = rsu_update_mcast; + ic->ic_parent = rsu_parent; + ic->ic_transmit = rsu_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT, @@ -406,7 +387,6 @@ rsu_attach(device_t self) return (0); -fail_ifalloc: fail_rom: usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); fail_usb: @@ -418,10 +398,11 @@ static int rsu_detach(device_t self) { struct rsu_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; - rsu_stop(ifp, 1); + RSU_LOCK(sc); + rsu_stop(sc); + RSU_UNLOCK(sc); usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); ieee80211_ifdetach(ic); @@ -431,7 +412,7 @@ rsu_detach(device_t self) rsu_free_tx_list(sc); rsu_free_rx_list(sc); - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -471,14 +452,11 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return (NULL); - uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return (NULL); + uvp = malloc(sizeof(struct rsu_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags, bssid, mac) != 0) { + flags, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -490,7 +468,7 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return (vap); @@ -508,9 +486,8 @@ rsu_vap_delete(struct ieee80211vap *vap) static void rsu_scan_start(struct ieee80211com *ic) { + struct rsu_softc *sc = ic->ic_softc; int error; - struct ifnet *ifp = ic->ic_ifp; - struct rsu_softc *sc = ifp->if_softc; /* Scanning is done by the firmware. */ RSU_LOCK(sc); @@ -676,11 +653,8 @@ rsu_getbuf(struct rsu_softc *sc) RSU_ASSERT_LOCKED(sc); bf = _rsu_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; + if (bf == NULL) DPRINTF("stop queue\n"); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -935,7 +909,7 @@ rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rsu_vap *uvp = RSU_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rsu_softc *sc = ic->ic_ifp->if_softc; + struct rsu_softc *sc = ic->ic_softc; struct ieee80211_node *ni; struct ieee80211_rateset *rs; enum ieee80211_state ostate; @@ -1033,29 +1007,27 @@ static int rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap) { struct r92s_fw_cmd_sitesurvey cmd; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; memset(&cmd, 0, sizeof(cmd)); - if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1) + if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->sc_scan_pass == 1) cmd.active = htole32(1); cmd.limit = htole32(48); - if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) { + if (sc->sc_scan_pass == 1 && vap->iv_des_nssid > 0) { /* Do a directed scan for second pass. */ cmd.ssidlen = htole32(vap->iv_des_ssid[0].len); memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid, vap->iv_des_ssid[0].len); } - DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass); + DPRINTF("sending site survey command, pass=%d\n", sc->sc_scan_pass); return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd))); } static int rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ndis_wlan_bssid_ex *bss; struct ndis_802_11_fixed_ies *fixed; @@ -1133,8 +1105,7 @@ rsu_disconnect(struct rsu_softc *sc) static void rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_channel *c; struct ndis_wlan_bssid_ex *bss; @@ -1165,7 +1136,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) IEEE80211_FC0_SUBTYPE_BEACON; wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; USETW(wh->i_dur, 0); - IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr); IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr); IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr); *(uint16_t *)wh->i_seq = 0; @@ -1173,7 +1144,6 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) /* Finalize mbuf. */ m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.rcvif = ifp; /* Fix the channel. */ c = ieee80211_find_channel_byieee(ic, le32toh(bss->config.dsconfig), @@ -1191,8 +1161,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) static void rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; struct r92s_event_join_bss *rsp; @@ -1228,8 +1197,7 @@ rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) static void rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTFN(4, "Rx event code=%d len=%d\n", code, len); @@ -1240,18 +1208,18 @@ rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) break; case R92S_EVT_SURVEY_DONE: DPRINTF("site survey pass %d done, found %d BSS\n", - sc->scan_pass, le32toh(*(uint32_t *)buf)); + sc->sc_scan_pass, le32toh(*(uint32_t *)buf)); if (vap->iv_state != IEEE80211_S_SCAN) break; /* Ignore if not scanning. */ - if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) { + if (sc->sc_scan_pass == 0 && vap->iv_des_nssid != 0) { /* Schedule a directed scan for hidden APs. */ - sc->scan_pass = 1; + sc->sc_scan_pass = 1; RSU_UNLOCK(sc); ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); RSU_LOCK(sc); break; } - sc->scan_pass = 0; + sc->sc_scan_pass = 0; break; case R92S_EVT_JOIN_BSS: if (vap->iv_state == IEEE80211_S_AUTH) @@ -1274,7 +1242,7 @@ XXX and disrupts the WLAN traffic. Disable for now. DPRINTF("WPS PBC pushed.\n"); break; case R92S_EVT_FWDBG: - if (ifp->if_flags & IFF_DEBUG) { + if (vap->iv_ifp->if_flags & IFF_DEBUG) { buf[60] = '\0'; printf("FWDBG: %s\n", (char *)buf); } @@ -1341,8 +1309,7 @@ rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt) static struct mbuf * rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct r92s_rx_stat *stat; uint32_t rxdw0, rxdw3; @@ -1355,11 +1322,11 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) rxdw3 = le32toh(stat->rxdw3); if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return NULL; } if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return NULL; } @@ -1377,11 +1344,9 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m == NULL)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return NULL; } - /* Finalize mbuf. */ - m->m_pkthdr.rcvif = ifp; /* Hardware does Rx TCP checksum offload. */ if (rxdw3 & R92S_RXDW3_TCPCHKVALID) { if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT)) @@ -1479,6 +1444,7 @@ static struct mbuf * rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) { struct rsu_softc *sc = data->sc; + struct ieee80211com *ic = &sc->sc_ic; struct r92s_rx_stat *stat; int len; @@ -1486,7 +1452,7 @@ rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) if (__predict_false(len < sizeof(*stat))) { DPRINTF("xfer too short %d\n", len); - if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } /* Determine if it is a firmware C2H event or an 802.11 frame. */ @@ -1503,8 +1469,7 @@ static void rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct rsu_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m = NULL, *next; @@ -1564,7 +1529,7 @@ tr_setup: } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } break; @@ -1572,35 +1537,16 @@ tr_setup: } - static void rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data) { - struct rsu_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; - - RSU_ASSERT_LOCKED(sc); - /* - * Do any tx complete callback. Note this must be done before releasing - * the node reference. - */ if (data->m) { - m = data->m; - if (m->m_flags & M_TXCB) { - /* XXX status? */ - ieee80211_process_callback(data->ni, m, 0); - } - m_freem(m); + /* XXX status? */ + ieee80211_tx_complete(data->ni, data->m, 0); data->m = NULL; - } - if (data->ni) { - ieee80211_free_node(data->ni); data->ni = NULL; } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void @@ -1608,7 +1554,7 @@ rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error, uint8_t which) { struct rsu_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; struct rsu_data *data; RSU_ASSERT_LOCKED(sc); @@ -1643,7 +1589,7 @@ tr_setup: rsu_txeof(xfer, data); STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); } - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(ic->ic_oerrors, 1); if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); @@ -1669,8 +1615,7 @@ static int rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct rsu_data *data) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ieee80211_key *k = NULL; @@ -1772,82 +1717,75 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, return (0); } -static void -rsu_start(struct ifnet *ifp) +static int +rsu_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct rsu_softc *sc = ifp->if_softc; - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; + struct rsu_softc *sc = ic->ic_softc; + int error; RSU_LOCK(sc); - rsu_start_locked(ifp); + if (!sc->sc_running) { + RSU_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RSU_UNLOCK(sc); + return (error); + } + rsu_start(sc); RSU_UNLOCK(sc); + + return (0); } static void -rsu_start_locked(struct ifnet *ifp) +rsu_start(struct rsu_softc *sc) { - struct rsu_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct rsu_data *bf; struct mbuf *m; RSU_ASSERT_LOCKED(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + bf = rsu_getbuf(sc); + if (bf == NULL) { + mbufq_prepend(&sc->sc_snd, m); break; + } + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; - bf = rsu_getbuf(sc); - if (bf == NULL) { - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - m_freem(m); - ieee80211_free_node(ni); - } else if (rsu_tx_start(sc, ni, m, bf) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if (rsu_tx_start(sc, ni, m, bf) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); ieee80211_free_node(ni); + break; } } } -static int -rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rsu_parent(struct ieee80211com *ic) { - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rsu_init(ifp->if_softc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rsu_stop(ifp, 1); + struct rsu_softc *sc = ic->ic_softc; + int startall = 0; + + RSU_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (!sc->sc_running) { + rsu_init(sc); + startall = 1; } - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } + } else if (sc->sc_running) + rsu_stop(sc); + RSU_UNLOCK(sc); - return (error); + if (startall) + ieee80211_start_all(ic); } /* @@ -2296,12 +2234,11 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rsu_softc *sc = ifp->if_softc; + struct rsu_softc *sc = ic->ic_softc; struct rsu_data *bf; /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!sc->sc_running) { m_freem(m); ieee80211_free_node(ni); return (ENETDOWN); @@ -2314,10 +2251,8 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, RSU_UNLOCK(sc); return (ENOBUFS); } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if (rsu_tx_start(sc, ni, m, bf) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); RSU_UNLOCK(sc); return (EIO); @@ -2328,23 +2263,17 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } static void -rsu_init(void *arg) +rsu_init(struct rsu_softc *sc) { - struct rsu_softc *sc = arg; - - RSU_LOCK(sc); - rsu_init_locked(arg); - RSU_UNLOCK(sc); -} - -static void -rsu_init_locked(struct rsu_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + uint8_t macaddr[IEEE80211_ADDR_LEN]; struct r92s_set_pwr_mode cmd; int error; int i; + RSU_ASSERT_LOCKED(sc); + /* Init host async commands ring. */ sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; @@ -2384,14 +2313,14 @@ rsu_init_locked(struct rsu_softc *sc) rsu_read_1(sc, 0xfe5c) | 0x80); /* Set MAC address. */ - rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp), - IEEE80211_ADDR_LEN); + IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr); + rsu_write_region_1(sc, R92S_MACID, macaddr, IEEE80211_ADDR_LEN); /* It really takes 1.5 seconds for the firmware to boot: */ usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2); - DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp))); - error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp), + DPRINTF("setting MAC address to %s\n", ether_sprintf(macaddr)); + error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, macaddr, IEEE80211_ADDR_LEN); if (error != 0) { device_printf(sc->sc_dev, "could not set MAC address\n"); @@ -2427,12 +2356,11 @@ rsu_init_locked(struct rsu_softc *sc) /* Set default channel. */ ic->ic_bss->ni_chan = ic->ic_ibss_chan; #endif - sc->scan_pass = 0; + sc->sc_scan_pass = 0; usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); /* We're ready to go. */ - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; return; fail: /* Need to stop all failed transfers, if any */ @@ -2441,22 +2369,11 @@ fail: } static void -rsu_stop(struct ifnet *ifp, int disable) -{ - struct rsu_softc *sc = ifp->if_softc; - - RSU_LOCK(sc); - rsu_stop_locked(ifp, disable); - RSU_UNLOCK(sc); -} - -static void -rsu_stop_locked(struct ifnet *ifp, int disable __unused) +rsu_stop(struct rsu_softc *sc) { - struct rsu_softc *sc = ifp->if_softc; int i; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_running = 0; sc->sc_calibrating = 0; taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL); |