diff options
Diffstat (limited to 'sys/dev/usb/wlan/if_ural.c')
-rw-r--r-- | sys/dev/usb/wlan/if_ural.c | 284 |
1 files changed, 178 insertions, 106 deletions
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index e8224ba..79a5be0 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -149,9 +149,8 @@ static int ural_tx_mgt(struct ural_softc *, struct mbuf *, struct ieee80211_node *); static int ural_tx_data(struct ural_softc *, struct mbuf *, struct ieee80211_node *); -static int ural_transmit(struct ieee80211com *, struct mbuf *); -static void ural_start(struct ural_softc *); -static void ural_parent(struct ieee80211com *); +static void ural_start(struct ifnet *); +static int ural_ioctl(struct ifnet *, u_long, caddr_t); static void ural_set_testmode(struct ural_softc *); static void ural_eeprom_read(struct ural_softc *, uint16_t, void *, int); @@ -172,12 +171,12 @@ static void ural_set_chan(struct ural_softc *, static void ural_disable_rf_tune(struct ural_softc *); static void ural_enable_tsf_sync(struct ural_softc *); static void ural_enable_tsf(struct ural_softc *); -static void ural_update_slot(struct ural_softc *); +static void ural_update_slot(struct ifnet *); static void ural_set_txpreamble(struct ural_softc *); static void ural_set_basicrates(struct ural_softc *, const struct ieee80211_channel *); static void ural_set_bssid(struct ural_softc *, const uint8_t *); -static void ural_set_macaddr(struct ural_softc *, const uint8_t *); +static void ural_set_macaddr(struct ural_softc *, uint8_t *); static void ural_update_promisc(struct ieee80211com *); static void ural_setpromisc(struct ural_softc *); static const char *ural_get_rf(int); @@ -185,7 +184,8 @@ static void ural_read_eeprom(struct ural_softc *); static int ural_bbp_init(struct ural_softc *); static void ural_set_txantenna(struct ural_softc *, int); static void ural_set_rxantenna(struct ural_softc *, int); -static void ural_init(struct ural_softc *); +static void ural_init_locked(struct ural_softc *); +static void ural_init(void *); static void ural_stop(struct ural_softc *); static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); @@ -422,7 +422,8 @@ ural_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct ural_softc *sc = device_get_softc(self); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp; + struct ieee80211com *ic; uint8_t iface_index, bands; int error; @@ -432,7 +433,6 @@ ural_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); - mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RAL_IFACE_INDEX; error = usbd_transfer_setup(uaa->device, @@ -455,6 +455,24 @@ ural_attach(device_t self) device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", sc->asic_rev, ural_get_rf(sc->rf_rev)); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + goto detach; + } + ic = ifp->if_l2com; + + ifp->if_softc = sc; + if_initname(ifp, "ural", device_get_unit(sc->sc_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = ural_init; + ifp->if_ioctl = ural_ioctl; + ifp->if_start = ural_start; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; + IFQ_SET_READY(&ifp->if_snd); + + 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 */ @@ -479,14 +497,13 @@ ural_attach(device_t self) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic); + ieee80211_ifattach(ic, sc->sc_bssid); ic->ic_update_promisc = ural_update_promisc; ic->ic_raw_xmit = ural_raw_xmit; ic->ic_scan_start = ural_scan_start; ic->ic_scan_end = ural_scan_end; ic->ic_set_channel = ural_set_channel; - ic->ic_parent = ural_parent; - ic->ic_transmit = ural_transmit; + ic->ic_vap_create = ural_vap_create; ic->ic_vap_delete = ural_vap_delete; @@ -510,7 +527,8 @@ static int ural_detach(device_t self) { struct ural_softc *sc = device_get_softc(self); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic; /* prevent further ioctls */ RAL_LOCK(sc); @@ -525,9 +543,11 @@ ural_detach(device_t self) ural_unsetup_tx_list(sc); RAL_UNLOCK(sc); - if (ic->ic_softc == sc) + if (ifp) { + ic = ifp->if_l2com; ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); + if_free(ifp); + } mtx_destroy(&sc->sc_mtx); return (0); @@ -560,7 +580,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ural_softc *sc = ic->ic_softc; + struct ural_softc *sc = ic->ic_ifp->if_softc; struct ural_vap *uvp; struct ieee80211vap *vap; @@ -574,7 +594,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -590,8 +610,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status, mac); + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); ic->ic_opmode = opmode; return vap; } @@ -615,8 +634,13 @@ ural_tx_free(struct ural_tx_data *data, int txerr) struct ural_softc *sc = data->sc; if (data->m != NULL) { - ieee80211_tx_complete(data->ni, data->m, txerr); + if (data->m->m_flags & M_TXCB) + ieee80211_process_callback(data->ni, data->m, + txerr ? ETIMEDOUT : 0); + m_freem(data->m); data->m = NULL; + + ieee80211_free_node(data->ni); data->ni = NULL; } STAILQ_INSERT_TAIL(&sc->tx_free, data, next); @@ -673,7 +697,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ural_vap *uvp = URAL_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ural_softc *sc = ic->ic_softc; + struct ural_softc *sc = ic->ic_ifp->if_softc; const struct ieee80211_txparam *tp; struct ieee80211_node *ni; struct mbuf *m; @@ -707,11 +731,11 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ieee80211_free_node(ni); return (-1); } - ural_update_slot(sc); + ural_update_slot(ic->ic_ifp); ural_set_txpreamble(sc); ural_set_basicrates(sc, ic->ic_bsschan); - IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); - ural_set_bssid(sc, ic->ic_macaddr); + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + ural_set_bssid(sc, sc->sc_bssid); } if (vap->iv_opmode == IEEE80211_M_HOSTAP || @@ -765,6 +789,7 @@ static void ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) { struct ural_softc *sc = usbd_xfer_softc(xfer); + struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap; struct ural_tx_data *data; struct mbuf *m; @@ -782,6 +807,9 @@ ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) ural_tx_free(data, 0); usbd_xfer_set_priv(xfer, NULL); + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -824,13 +852,16 @@ tr_setup: usbd_transfer_submit(xfer); } - ural_start(sc); + RAL_UNLOCK(sc); + ural_start(ifp); + RAL_LOCK(sc); break; default: /* Error */ DPRINTFN(11, "transfer error, %s\n", usbd_errstr(error)); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); data = usbd_xfer_get_priv(xfer); if (data != NULL) { ural_tx_free(data, error); @@ -852,7 +883,8 @@ static void ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct ural_softc *sc = usbd_xfer_softc(xfer); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_node *ni; struct mbuf *m = NULL; struct usb_page_cache *pc; @@ -870,7 +902,7 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) if (len < (int)(RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN)) { DPRINTF("%s: xfer too short %d\n", device_get_nameunit(sc->sc_dev), len); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto tr_setup; } @@ -889,19 +921,20 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) * filled RAL_TXRX_CSR2: */ DPRINTFN(5, "PHY or CRC error\n"); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto tr_setup; } m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { DPRINTF("could not allocate mbuf\n"); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto tr_setup; } usbd_copy_out(pc, 0, mtod(m, uint8_t *), len); /* finalize mbuf */ + m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; if (ieee80211_radiotap_active(ic)) { @@ -940,8 +973,10 @@ tr_setup: } else (void) ieee80211_input_all(ic, m, rssi, nf); } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + ural_start(ifp); RAL_LOCK(sc); - ural_start(sc); return; default: /* Error */ @@ -981,7 +1016,8 @@ static void ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, uint32_t flags, int len, int rate) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int remainder; @@ -1030,10 +1066,12 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; const struct ieee80211_txparam *tp; struct ural_tx_data *data; if (sc->tx_nfree == 0) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; m_freem(m0); ieee80211_free_node(ni); return (EIO); @@ -1310,73 +1348,78 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) return 0; } -static int -ural_transmit(struct ieee80211com *ic, struct mbuf *m) -{ - struct ural_softc *sc = ic->ic_softc; - int error; - - RAL_LOCK(sc); - if (!sc->sc_running) { - RAL_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - RAL_UNLOCK(sc); - return (error); - } - ural_start(sc); - RAL_UNLOCK(sc); - - return (0); -} - static void -ural_start(struct ural_softc *sc) +ural_start(struct ifnet *ifp) { + struct ural_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - RAL_LOCK_ASSERT(sc, MA_OWNED); - - if (sc->sc_running == 0) + RAL_LOCK(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + RAL_UNLOCK(sc); return; - - while (sc->tx_nfree >= RAL_TX_MINFREE && - (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + } + for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + if (sc->tx_nfree < RAL_TX_MINFREE) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (ural_tx_data(sc, m, ni) != 0) { - if_inc_counter(ni->ni_vap->iv_ifp, - IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; } } + RAL_UNLOCK(sc); } -static void -ural_parent(struct ieee80211com *ic) +static int +ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct ural_softc *sc = ic->ic_softc; + struct ural_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error; int startall = 0; RAL_LOCK(sc); - if (sc->sc_detached) { + error = sc->sc_detached ? ENXIO : 0; + RAL_UNLOCK(sc); + if (error) + return (error); + + switch (cmd) { + case SIOCSIFFLAGS: + RAL_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + ural_init_locked(sc); + startall = 1; + } else + ural_setpromisc(sc); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ural_stop(sc); + } RAL_UNLOCK(sc); - return; + if (startall) + ieee80211_start_all(ic); + break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; + default: + error = ether_ioctl(ifp, cmd, data); + break; } - if (ic->ic_nrunning > 0) { - if (sc->sc_running == 0) { - ural_init(sc); - startall = 1; - } else - ural_setpromisc(sc); - } else if (sc->sc_running) - ural_stop(sc); - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + return error; } static void @@ -1571,22 +1614,23 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) static void ural_scan_start(struct ieee80211com *ic) { - struct ural_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ural_softc *sc = ifp->if_softc; RAL_LOCK(sc); ural_write(sc, RAL_TXRX_CSR19, 0); - ural_set_bssid(sc, ieee80211broadcastaddr); + ural_set_bssid(sc, ifp->if_broadcastaddr); RAL_UNLOCK(sc); } static void ural_scan_end(struct ieee80211com *ic) { - struct ural_softc *sc = ic->ic_softc; + struct ural_softc *sc = ic->ic_ifp->if_softc; RAL_LOCK(sc); ural_enable_tsf_sync(sc); - ural_set_bssid(sc, ic->ic_macaddr); + ural_set_bssid(sc, sc->sc_bssid); RAL_UNLOCK(sc); } @@ -1594,7 +1638,7 @@ ural_scan_end(struct ieee80211com *ic) static void ural_set_channel(struct ieee80211com *ic) { - struct ural_softc *sc = ic->ic_softc; + struct ural_softc *sc = ic->ic_ifp->if_softc; RAL_LOCK(sc); ural_set_chan(sc, ic->ic_curchan); @@ -1604,7 +1648,8 @@ ural_set_channel(struct ieee80211com *ic) static void ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint8_t power, tmp; int i, chan; @@ -1735,7 +1780,8 @@ ural_disable_rf_tune(struct ural_softc *sc) static void ural_enable_tsf_sync(struct ural_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload, tmp; @@ -1771,9 +1817,10 @@ ural_enable_tsf(struct ural_softc *sc) #define RAL_RXTX_TURNAROUND 5 /* us */ static void -ural_update_slot(struct ural_softc *sc) +ural_update_slot(struct ifnet *ifp) { - struct ieee80211com *ic = &sc->sc_ic; + struct ural_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; uint16_t slottime, sifs, eifs; slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; @@ -1798,7 +1845,8 @@ ural_update_slot(struct ural_softc *sc) static void ural_set_txpreamble(struct ural_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t tmp; tmp = ural_read(sc, RAL_TXRX_CSR10); @@ -1845,7 +1893,7 @@ ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid) } static void -ural_set_macaddr(struct ural_softc *sc, const uint8_t *addr) +ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) { uint16_t tmp; @@ -1864,17 +1912,18 @@ ural_set_macaddr(struct ural_softc *sc, const uint8_t *addr) static void ural_setpromisc(struct ural_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; tmp = ural_read(sc, RAL_TXRX_CSR2); tmp &= ~RAL_DROP_NOT_TO_ME; - if (sc->sc_ic.ic_promisc == 0) + if (!(ifp->if_flags & IFF_PROMISC)) tmp |= RAL_DROP_NOT_TO_ME; ural_write(sc, RAL_TXRX_CSR2, tmp); - DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc ? + DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); } @@ -1883,9 +1932,11 @@ ural_update_promisc(struct ieee80211com *ic) { struct ural_softc *sc = ic->ic_softc; + if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + RAL_LOCK(sc); - if (sc->sc_running) - ural_setpromisc(sc); + ural_setpromisc(sc); RAL_UNLOCK(sc); } @@ -1907,7 +1958,6 @@ ural_get_rf(int rev) static void ural_read_eeprom(struct ural_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; uint16_t val; ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2); @@ -1920,7 +1970,7 @@ ural_read_eeprom(struct ural_softc *sc) sc->nb_ant = val & 0x3; /* read MAC address */ - ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_macaddr, 6); + ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, sc->sc_bssid, 6); /* read default values for BBP registers */ ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); @@ -2014,11 +2064,11 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna) } static void -ural_init(struct ural_softc *sc) +ural_init_locked(struct ural_softc *sc) { #define N(a) ((int)(sizeof (a) / sizeof ((a)[0]))) - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t tmp; int i, ntries; @@ -2065,7 +2115,7 @@ ural_init(struct ural_softc *sc) ural_set_txantenna(sc, sc->tx_ant); ural_set_rxantenna(sc, sc->rx_ant); - ural_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); + ural_set_macaddr(sc, IF_LLADDR(ifp)); /* * Allocate Tx and Rx xfer queues. @@ -2078,12 +2128,13 @@ ural_init(struct ural_softc *sc) tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION; if (ic->ic_opmode != IEEE80211_M_HOSTAP) tmp |= RAL_DROP_TODS; - if (ic->ic_promisc == 0) + if (!(ifp->if_flags & IFF_PROMISC)) tmp |= RAL_DROP_NOT_TO_ME; } ural_write(sc, RAL_TXRX_CSR2, tmp); - sc->sc_running = 1; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; usbd_xfer_set_stall(sc->sc_xfer[URAL_BULK_WR]); usbd_transfer_start(sc->sc_xfer[URAL_BULK_RD]); return; @@ -2093,12 +2144,28 @@ fail: ural_stop(sc); } static void +ural_init(void *priv) +{ + struct ural_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + RAL_LOCK(sc); + ural_init_locked(sc); + RAL_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void ural_stop(struct ural_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc, MA_OWNED); - sc->sc_running = 0; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* * Drain all the transfers, if not already drained: @@ -2126,23 +2193,27 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ural_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ural_softc *sc = ifp->if_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!sc->sc_running) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->tx_nfree < RAL_TX_MINFREE) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return EIO; } + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2161,6 +2232,7 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, RAL_UNLOCK(sc); return 0; bad: + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); RAL_UNLOCK(sc); ieee80211_free_node(ni); return EIO; /* XXX */ @@ -2194,7 +2266,8 @@ ural_ratectl_task(void *arg, int pending) struct ural_vap *uvp = arg; struct ieee80211vap *vap = &uvp->vap; struct ieee80211com *ic = vap->iv_ic; - struct ural_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ural_softc *sc = ifp->if_softc; struct ieee80211_node *ni; int ok, fail; int sum, retrycnt; @@ -2213,8 +2286,7 @@ ural_ratectl_task(void *arg, int pending) ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt); (void) ieee80211_ratectl_rate(ni, NULL, 0); - /* count TX retry-fail as Tx errors */ - if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail); + if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */ usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp); RAL_UNLOCK(sc); |