diff options
Diffstat (limited to 'sys/dev/usb/wlan/if_urtw.c')
-rw-r--r-- | sys/dev/usb/wlan/if_urtw.c | 338 |
1 files changed, 127 insertions, 211 deletions
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index f8b77d4..f0d2674 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -651,11 +651,11 @@ static struct ieee80211vap *urtw_vap_create(struct ieee80211com *, int, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void urtw_vap_delete(struct ieee80211vap *); -static void urtw_init(void *); -static void urtw_stop(struct ifnet *); -static void urtw_stop_locked(struct ifnet *); -static int urtw_ioctl(struct ifnet *, u_long, caddr_t); -static void urtw_start(struct ifnet *); +static void urtw_init(struct urtw_softc *); +static void urtw_stop(struct urtw_softc *); +static void urtw_parent(struct ieee80211com *); +static int urtw_transmit(struct ieee80211com *, struct mbuf *); +static void urtw_start(struct urtw_softc *); static int urtw_alloc_rx_data_list(struct urtw_softc *); static int urtw_alloc_tx_data_list(struct urtw_softc *); static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *, @@ -784,8 +784,7 @@ urtw_attach(device_t dev) int ret = ENXIO; struct urtw_softc *sc = device_get_softc(dev); struct usb_attach_arg *uaa = device_get_ivars(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */ uint16_t n_setup; uint32_t data; @@ -807,6 +806,7 @@ urtw_attach(device_t dev) TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc); TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc); callout_init(&sc->sc_watchdog_ch, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); if (sc->sc_flags & URTW_RTL8187B) { setup_start = urtw_8187b_usbconfig; @@ -861,26 +861,6 @@ urtw_attach(device_t dev) sc->sc_currate = 3; sc->sc_preamble_mode = urtw_preamble_mode; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not allocate ifnet\n"); - ret = ENOMEM; - goto fail1; - } - - ifp->if_softc = sc; - if_initname(ifp, "urtw", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = urtw_init; - ifp->if_ioctl = urtw_ioctl; - ifp->if_start = urtw_start; - /* XXX URTW_TX_DATA_LIST_COUNT */ - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -901,7 +881,7 @@ urtw_attach(device_t dev) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_raw_xmit = urtw_raw_xmit; ic->ic_scan_start = urtw_scan_start; ic->ic_scan_end = urtw_scan_end; @@ -910,6 +890,8 @@ urtw_attach(device_t dev) ic->ic_vap_create = urtw_vap_create; ic->ic_vap_delete = urtw_vap_delete; ic->ic_update_mcast = urtw_update_mcast; + ic->ic_parent = urtw_parent; + ic->ic_transmit = urtw_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -923,8 +905,9 @@ urtw_attach(device_t dev) ieee80211_announce(ic); return (0); -fail: URTW_UNLOCK(sc); -fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ? +fail: + URTW_UNLOCK(sc); + usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS : URTW_8187L_N_XFERS); fail0: return (ret); @@ -934,18 +917,16 @@ static int urtw_detach(device_t dev) { struct urtw_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; unsigned int x; unsigned int n_xfers; /* Prevent further ioctls */ URTW_LOCK(sc); sc->sc_flags |= URTW_DETACHED; + urtw_stop(sc); URTW_UNLOCK(sc); - urtw_stop(ifp); - ieee80211_draintask(ic, &sc->sc_updateslot_task); ieee80211_draintask(ic, &sc->sc_led_task); @@ -979,7 +960,7 @@ urtw_detach(device_t dev) usbd_transfer_unsetup(sc->sc_xfer, n_xfers); ieee80211_ifdetach(ic); - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); } @@ -1032,15 +1013,12 @@ urtw_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 urtw_vap *) malloc(sizeof(struct urtw_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return (NULL); + uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -1052,7 +1030,7 @@ urtw_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); } @@ -1067,15 +1045,15 @@ urtw_vap_delete(struct ieee80211vap *vap) } static void -urtw_init_locked(void *arg) +urtw_init(struct urtw_softc *sc) { - int ret; - struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; usb_error_t error; + int ret; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - urtw_stop_locked(ifp); + URTW_ASSERT_LOCKED(sc); + + if (sc->sc_flags & URTW_RUNNING) + urtw_stop(sc); error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) : urtw_adapter_start(sc); @@ -1105,24 +1083,13 @@ urtw_init_locked(void *arg) if (sc->sc_flags & URTW_RTL8187B) usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= URTW_RUNNING; callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); fail: return; } -static void -urtw_init(void *arg) -{ - struct urtw_softc *sc = arg; - - URTW_LOCK(sc); - urtw_init_locked(arg); - URTW_UNLOCK(sc); -} - static usb_error_t urtw_adapter_start_b(struct urtw_softc *sc) { @@ -1215,6 +1182,7 @@ fail: static usb_error_t urtw_adapter_start(struct urtw_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; usb_error_t error; error = urtw_reset(sc); @@ -1234,8 +1202,8 @@ urtw_adapter_start(struct urtw_softc *sc) if (error) goto fail; /* applying MAC address again. */ - urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]); - urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff); + urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]); + urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff); error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); if (error) goto fail; @@ -1338,13 +1306,14 @@ urtw_do_request(struct urtw_softc *sc, } static void -urtw_stop_locked(struct ifnet *ifp) +urtw_stop(struct urtw_softc *sc) { - struct urtw_softc *sc = ifp->if_softc; uint8_t data8; usb_error_t error; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + URTW_ASSERT_LOCKED(sc); + + sc->sc_flags &= ~URTW_RUNNING; error = urtw_intr_disable(sc); if (error) @@ -1377,16 +1346,6 @@ fail: } static void -urtw_stop(struct ifnet *ifp) -{ - struct urtw_softc *sc = ifp->if_softc; - - URTW_LOCK(sc); - urtw_stop_locked(ifp); - URTW_UNLOCK(sc); -} - -static void urtw_abort_xfers(struct urtw_softc *sc) { int i, max; @@ -1401,72 +1360,71 @@ urtw_abort_xfers(struct urtw_softc *sc) usbd_transfer_stop(sc->sc_xfer[i]); } -static int -urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +urtw_parent(struct ieee80211com *ic) { - struct urtw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error; + struct urtw_softc *sc = ic->ic_softc; int startall = 0; URTW_LOCK(sc); - error = (sc->sc_flags & URTW_DETACHED) ? ENXIO : 0; - URTW_UNLOCK(sc); - if (error) - return (error); + if (sc->sc_flags & URTW_DETACHED) { + URTW_UNLOCK(sc); + return; + } - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->sc_if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) - urtw_set_multi(sc); - } else { - urtw_init(ifp->if_softc); - startall = 1; - } + if (ic->ic_nrunning > 0) { + if (sc->sc_flags & URTW_RUNNING) { + if (ic->ic_promisc > 0 || ic->ic_allmulti > 0) + urtw_set_multi(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - urtw_stop(ifp); + urtw_init(sc); + startall = 1; } - sc->sc_if_flags = ifp->if_flags; - 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_flags & URTW_RUNNING) + urtw_stop(sc); + URTW_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); +} + +static int +urtw_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct urtw_softc *sc = ic->ic_softc; + int error; + + URTW_LOCK(sc); + if ((sc->sc_flags & URTW_RUNNING) == 0) { + URTW_UNLOCK(sc); + return (ENXIO); } - return (error); + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + URTW_UNLOCK(sc); + return (error); + } + urtw_start(sc); + URTW_UNLOCK(sc); + + return (0); } static void -urtw_start(struct ifnet *ifp) +urtw_start(struct urtw_softc *sc) { struct urtw_data *bf; - struct urtw_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + URTW_ASSERT_LOCKED(sc); + + if ((sc->sc_flags & URTW_RUNNING) == 0) return; - URTW_LOCK(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { bf = urtw_getbuf(sc); if (bf == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); + mbufq_prepend(&sc->sc_snd, m); break; } @@ -1474,7 +1432,8 @@ urtw_start(struct ifnet *ifp) m->m_pkthdr.rcvif = NULL; if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + 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; @@ -1483,7 +1442,6 @@ urtw_start(struct ifnet *ifp) sc->sc_txtimer = 5; callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); } - URTW_UNLOCK(sc); } static int @@ -1565,12 +1523,11 @@ urtw_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 urtw_softc *sc = ic->ic_softc; struct urtw_data *bf; - struct urtw_softc *sc = ifp->if_softc; /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & URTW_RUNNING)) { m_freem(m); ieee80211_free_node(ni); return ENETDOWN; @@ -1584,10 +1541,8 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return (ENOBUFS); /* XXX */ } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); URTW_UNLOCK(sc); return (EIO); @@ -1615,8 +1570,7 @@ urtw_scan_end(struct ieee80211com *ic) static void urtw_set_channel(struct ieee80211com *ic) { - struct urtw_softc *sc = ic->ic_ifp->if_softc; - struct ifnet *ifp = sc->sc_ifp; + struct urtw_softc *sc = ic->ic_softc; uint32_t data, orig; usb_error_t error; @@ -1626,7 +1580,7 @@ urtw_set_channel(struct ieee80211com *ic) * initialization would be failed if setting a channel is called before * the init have done. */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!(sc->sc_flags & URTW_RUNNING)) return; if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan) @@ -1673,11 +1627,10 @@ static int urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct urtw_data *data, int prior) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *); struct ieee80211_key *k; const struct ieee80211_txparam *tp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = { sc->sc_xfer[URTW_8187B_BULK_TX_BE], @@ -1862,7 +1815,7 @@ static int urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct urtw_softc *sc = ic->ic_ifp->if_softc; + struct urtw_softc *sc = ic->ic_softc; struct urtw_vap *uvp = URTW_VAP(vap); struct ieee80211_node *ni; usb_error_t error = 0; @@ -1915,12 +1868,11 @@ static void urtw_watchdog(void *arg) { struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; if (sc->sc_txtimer > 0) { if (--sc->sc_txtimer == 0) { device_printf(sc->sc_dev, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); return; } callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); @@ -1930,17 +1882,7 @@ urtw_watchdog(void *arg) static void urtw_set_multi(void *arg) { - struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - - if (!(ifp->if_flags & IFF_UP)) - return; - - /* - * XXX don't know how to set a device. Lack of docs. Just try to set - * IFF_ALLMULTI flag here. - */ - ifp->if_flags |= IFF_ALLMULTI; + /* XXX don't know how to set a device. Lack of docs. */ } static usb_error_t @@ -2002,8 +1944,7 @@ urtw_rtl2rate(uint32_t rate) static usb_error_t urtw_update_msr(struct urtw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t data; usb_error_t error; @@ -2144,24 +2085,25 @@ urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data) static usb_error_t urtw_get_macaddr(struct urtw_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; uint32_t data; usb_error_t error; error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data); if (error != 0) goto fail; - sc->sc_bssid[0] = data & 0xff; - sc->sc_bssid[1] = (data & 0xff00) >> 8; + ic->ic_macaddr[0] = data & 0xff; + ic->ic_macaddr[1] = (data & 0xff00) >> 8; error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data); if (error != 0) goto fail; - sc->sc_bssid[2] = data & 0xff; - sc->sc_bssid[3] = (data & 0xff00) >> 8; + ic->ic_macaddr[2] = data & 0xff; + ic->ic_macaddr[3] = (data & 0xff00) >> 8; error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data); if (error != 0) goto fail; - sc->sc_bssid[4] = data & 0xff; - sc->sc_bssid[5] = (data & 0xff00) >> 8; + ic->ic_macaddr[4] = data & 0xff; + ic->ic_macaddr[5] = (data & 0xff00) >> 8; fail: return (error); } @@ -3233,7 +3175,7 @@ fail: static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *sc) { -#define N(a) ((int)(sizeof(a) / sizeof((a)[0]))) + struct ieee80211com *ic = &sc->sc_ic; int i; uint8_t data8; usb_error_t error; @@ -3281,8 +3223,8 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) urtw_write8_m(sc, URTW_CONFIG1, data8); /* applying MAC address again. */ - urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]); - urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff); + urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]); + urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff); error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); if (error) @@ -3293,7 +3235,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) /* * MAC configuration */ - for (i = 0; i < N(urtw_8225v2b_rf_part1); i++) + for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++) urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg, urtw_8225v2b_rf_part1[i].val); urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50); @@ -3326,7 +3268,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff); usb_pause_mtx(&sc->sc_mtx, 1100); - for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) { + for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) { urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg, urtw_8225v2b_rf_part0[i].val); usb_pause_mtx(&sc->sc_mtx, 1); @@ -3372,7 +3314,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) } urtw_8187_write_phy_ofdm(sc, 0x80, 0x10); - for (i = 0; i < N(urtw_8225v2b_rf_part2); i++) + for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++) urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val); urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c); @@ -3787,8 +3729,7 @@ static void urtw_led_ch(void *arg) { struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ieee80211_runtask(ic, &sc->sc_led_task); } @@ -3935,8 +3876,7 @@ fail: static usb_error_t urtw_rx_setconf(struct urtw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t data; usb_error_t error; @@ -3961,7 +3901,7 @@ urtw_rx_setconf(struct urtw_softc *sc) data = data | URTW_RX_FILTER_CRCERR; if (ic->ic_opmode == IEEE80211_M_MONITOR || - (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { + ic->ic_promisc > 0 || ic->ic_allmulti > 0) { data = data | URTW_RX_FILTER_ALLMAC; } else { data = data | URTW_RX_FILTER_NICMAC; @@ -3988,14 +3928,13 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, struct ieee80211_frame *wh; struct mbuf *m, *mnew; struct urtw_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t noise = 0, rate; usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); if (actlen < (int)URTW_MIN_RXBUFSZ) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -4006,7 +3945,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, (actlen - (sizeof(struct urtw_8187b_rxhdr)))); flen = le32toh(rx->flag) & 0xfff; if (flen > actlen) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf; @@ -4020,7 +3959,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, (actlen - (sizeof(struct urtw_8187l_rxhdr)))); flen = le32toh(rx->flag) & 0xfff; if (flen > actlen) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -4032,7 +3971,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -4041,7 +3980,6 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, data->buf = mtod(mnew, uint8_t *); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN; if (ieee80211_radiotap_active(ic)) { @@ -4067,8 +4005,7 @@ static void urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtw_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; @@ -4129,7 +4066,7 @@ 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 setup; } break; @@ -4143,7 +4080,7 @@ static void urtw_txstatus_eof(struct usb_xfer *xfer) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; int actlen, type, pktretry, seq; uint64_t val; @@ -4158,7 +4095,7 @@ urtw_txstatus_eof(struct usb_xfer *xfer) pktretry = val & 0xff; seq = (val >> 16) & 0xff; if (pktretry == URTW_TX_MAXRETRY) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(ic->ic_oerrors, 1); DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n", pktretry, seq); } @@ -4168,7 +4105,7 @@ static void urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0); URTW_ASSERT_LOCKED(sc); @@ -4186,7 +4123,7 @@ setup: default: 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 setup; } break; @@ -4197,38 +4134,22 @@ static void urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; URTW_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; } sc->sc_txtimer = 0; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct urtw_data *data; URTW_ASSERT_LOCKED(sc); @@ -4256,18 +4177,17 @@ setup: usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - URTW_UNLOCK(sc); - urtw_start(ifp); - URTW_LOCK(sc); + urtw_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); if (data == NULL) goto setup; if (data->ni != NULL) { + if_inc_counter(data->ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(data->ni); data->ni = NULL; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); @@ -4301,12 +4221,8 @@ urtw_getbuf(struct urtw_softc *sc) URTW_ASSERT_LOCKED(sc); bf = _urtw_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; - + if (bf == NULL) DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -4378,14 +4294,14 @@ static void urtw_updateslottask(void *arg, int pending) { struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int error; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - URTW_LOCK(sc); + if ((sc->sc_flags & URTW_RUNNING) == 0) { + URTW_UNLOCK(sc); + return; + } if (sc->sc_flags & URTW_RTL8187B) { urtw_write8_m(sc, URTW_SIFS, 0x22); if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) |