diff options
Diffstat (limited to 'sys/dev/usb/wlan/if_rum.c')
-rw-r--r-- | sys/dev/usb/wlan/if_rum.c | 302 |
1 files changed, 190 insertions, 112 deletions
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 6a558f6..d5142ea 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -175,9 +175,8 @@ static int rum_tx_raw(struct rum_softc *, struct mbuf *, const struct ieee80211_bpf_params *); static int rum_tx_data(struct rum_softc *, struct mbuf *, struct ieee80211_node *); -static int rum_transmit(struct ieee80211com *, struct mbuf *); -static void rum_start(struct rum_softc *); -static void rum_parent(struct ieee80211com *); +static void rum_start(struct ifnet *); +static int rum_ioctl(struct ifnet *, u_long, caddr_t); static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, int); static uint32_t rum_read(struct rum_softc *, uint16_t); @@ -199,7 +198,7 @@ static void rum_set_chan(struct rum_softc *, struct ieee80211_channel *); static void rum_enable_tsf_sync(struct rum_softc *); static void rum_enable_tsf(struct rum_softc *); -static void rum_update_slot(struct rum_softc *); +static void rum_update_slot(struct ifnet *); static void rum_set_bssid(struct rum_softc *, const uint8_t *); static void rum_set_macaddr(struct rum_softc *, const uint8_t *); static void rum_update_mcast(struct ieee80211com *); @@ -208,7 +207,8 @@ static void rum_setpromisc(struct rum_softc *); static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); -static void rum_init(struct rum_softc *); +static void rum_init_locked(struct rum_softc *); +static void rum_init(void *); static void rum_stop(struct rum_softc *); static void rum_load_microcode(struct rum_softc *, const uint8_t *, size_t); @@ -425,7 +425,8 @@ rum_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct rum_softc *sc = device_get_softc(self); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; + struct ifnet *ifp; uint8_t iface_index, bands; uint32_t tmp; int error, ntries; @@ -436,7 +437,6 @@ rum_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 = RT2573_IFACE_INDEX; error = usbd_transfer_setup(uaa->device, &iface_index, @@ -470,6 +470,24 @@ rum_attach(device_t self) rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); RUM_UNLOCK(sc); + 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, "rum", device_get_unit(sc->sc_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = rum_init; + ifp->if_ioctl = rum_ioctl; + ifp->if_start = rum_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 */ @@ -494,14 +512,13 @@ rum_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 = rum_update_promisc; ic->ic_raw_xmit = rum_raw_xmit; ic->ic_scan_start = rum_scan_start; ic->ic_scan_end = rum_scan_end; ic->ic_set_channel = rum_set_channel; - ic->ic_transmit = rum_transmit; - ic->ic_parent = rum_parent; + ic->ic_vap_create = rum_vap_create; ic->ic_vap_delete = rum_vap_delete; ic->ic_update_mcast = rum_update_mcast; @@ -526,6 +543,8 @@ static int rum_detach(device_t self) { struct rum_softc *sc = device_get_softc(self); + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic; /* Prevent further ioctls */ RUM_LOCK(sc); @@ -540,9 +559,11 @@ rum_detach(device_t self) rum_unsetup_tx_list(sc); RUM_UNLOCK(sc); - if (sc->sc_ic.ic_softc == sc) - ieee80211_ifdetach(&sc->sc_ic); - mbufq_drain(&sc->sc_snd); + if (ifp) { + ic = ifp->if_l2com; + ieee80211_ifdetach(ic); + if_free(ifp); + } mtx_destroy(&sc->sc_mtx); return (0); } @@ -574,18 +595,21 @@ rum_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 rum_softc *sc = ic->ic_softc; + struct rum_softc *sc = ic->ic_ifp->if_softc; struct rum_vap *rvp; struct ieee80211vap *vap; if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - rvp = malloc(sizeof(struct rum_vap), M_80211_VAP, M_WAITOK | M_ZERO); + rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; vap = &rvp->vap; /* 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(rvp, M_80211_VAP); return (NULL); @@ -600,8 +624,7 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); 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; } @@ -625,8 +648,13 @@ rum_tx_free(struct rum_tx_data *data, int txerr) struct rum_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); @@ -683,7 +711,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rum_vap *rvp = RUM_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rum_softc *sc = ic->ic_softc; + struct rum_softc *sc = ic->ic_ifp->if_softc; const struct ieee80211_txparam *tp; enum ieee80211_state ostate; struct ieee80211_node *ni; @@ -717,12 +745,12 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ieee80211_free_node(ni); return (-1); } - rum_update_slot(sc); + rum_update_slot(ic->ic_ifp); rum_enable_mrr(sc); rum_set_txpreamble(sc); rum_set_basicrates(sc); - IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); - rum_set_bssid(sc, ic->ic_macaddr); + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + rum_set_bssid(sc, sc->sc_bssid); } if (vap->iv_opmode == IEEE80211_M_HOSTAP || @@ -752,6 +780,7 @@ static void rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) { struct rum_softc *sc = usbd_xfer_softc(xfer); + struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap; struct rum_tx_data *data; struct mbuf *m; @@ -770,6 +799,9 @@ rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) rum_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: @@ -812,14 +844,16 @@ tr_setup: usbd_transfer_submit(xfer); } - rum_start(sc); + RUM_UNLOCK(sc); + rum_start(ifp); + RUM_LOCK(sc); break; default: /* Error */ DPRINTFN(11, "transfer error, %s\n", usbd_errstr(error)); - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); data = usbd_xfer_get_priv(xfer); if (data != NULL) { rum_tx_free(data, error); @@ -846,7 +880,8 @@ static void rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct rum_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; @@ -864,7 +899,7 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) if (len < (int)(RT2573_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; } @@ -881,20 +916,21 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) * filled RUM_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, RT2573_RX_DESC_SIZE, 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)) { @@ -932,8 +968,10 @@ tr_setup: (void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR); } + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_IS_EMPTY(&ifp->if_snd)) + rum_start(ifp); RUM_LOCK(sc); - rum_start(sc); return; default: /* Error */ @@ -973,7 +1011,8 @@ static void rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, uint32_t flags, uint16_t xflags, 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; @@ -1070,7 +1109,8 @@ static int rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_tx_data *data; struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; @@ -1181,7 +1221,8 @@ static int rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_tx_data *data; struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; @@ -1258,73 +1299,80 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) return 0; } -static int -rum_transmit(struct ieee80211com *ic, struct mbuf *m) -{ - struct rum_softc *sc = ic->ic_softc; - int error; - - RUM_LOCK(sc); - if (!sc->sc_running) { - RUM_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - RUM_UNLOCK(sc); - return (error); - } - rum_start(sc); - RUM_UNLOCK(sc); - - return (0); -} - static void -rum_start(struct rum_softc *sc) +rum_start(struct ifnet *ifp) { + struct rum_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - RUM_LOCK_ASSERT(sc, MA_OWNED); - - if (!sc->sc_running) + RUM_LOCK(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + RUM_UNLOCK(sc); return; - - while (sc->tx_nfree >= RUM_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 < RUM_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 (rum_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; } } + RUM_UNLOCK(sc); } -static void -rum_parent(struct ieee80211com *ic) +static int +rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct rum_softc *sc = ic->ic_softc; + struct rum_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error; int startall = 0; RUM_LOCK(sc); - if (sc->sc_detached) { + error = sc->sc_detached ? ENXIO : 0; + RUM_UNLOCK(sc); + if (error) + return (error); + + switch (cmd) { + case SIOCSIFFLAGS: + RUM_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + rum_init_locked(sc); + startall = 1; + } else + rum_setpromisc(sc); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rum_stop(sc); + } RUM_UNLOCK(sc); - return; + 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; } - if (ic->ic_nrunning > 0) { - if (!sc->sc_running) { - rum_init(sc); - startall = 1; - } else - rum_setpromisc(sc); - } else if (sc->sc_running) - rum_stop(sc); - RUM_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + return error; } static void @@ -1524,7 +1572,8 @@ rum_select_antenna(struct rum_softc *sc) static void rum_enable_mrr(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR4); @@ -1540,7 +1589,8 @@ rum_enable_mrr(struct rum_softc *sc) static void rum_set_txpreamble(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR4); @@ -1555,7 +1605,8 @@ rum_set_txpreamble(struct rum_softc *sc) static void rum_set_basicrates(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; /* update basic rate set */ if (ic->ic_curmode == IEEE80211_MODE_11B) { @@ -1620,7 +1671,8 @@ rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) static void rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; int8_t power; @@ -1696,7 +1748,8 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) static void rum_enable_tsf_sync(struct rum_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); uint32_t tmp; @@ -1731,9 +1784,10 @@ rum_enable_tsf(struct rum_softc *sc) } static void -rum_update_slot(struct rum_softc *sc) +rum_update_slot(struct ifnet *ifp) { - struct ieee80211com *ic = &sc->sc_ic; + struct rum_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; uint8_t slottime; uint32_t tmp; @@ -1773,17 +1827,18 @@ rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) static void rum_setpromisc(struct rum_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR0); tmp &= ~RT2573_DROP_NOT_TO_ME; - if (sc->sc_ic.ic_promisc == 0) + if (!(ifp->if_flags & IFF_PROMISC)) tmp |= RT2573_DROP_NOT_TO_ME; rum_write(sc, RT2573_TXRX_CSR0, tmp); - DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc > 0 ? + DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); } @@ -1792,11 +1847,10 @@ rum_update_promisc(struct ieee80211com *ic) { struct rum_softc *sc = ic->ic_softc; - RUM_LOCK(sc); - if (!sc->sc_running) { - RUM_UNLOCK(sc); + if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - } + + RUM_LOCK(sc); rum_setpromisc(sc); RUM_UNLOCK(sc); } @@ -1833,7 +1887,7 @@ rum_read_eeprom(struct rum_softc *sc) #endif /* read MAC address */ - rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_ic.ic_macaddr, 6); + rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6); rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2); val = le16toh(val); @@ -1940,10 +1994,10 @@ rum_bbp_init(struct rum_softc *sc) } static void -rum_init(struct rum_softc *sc) +rum_init_locked(struct rum_softc *sc) { - 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; uint32_t tmp; usb_error_t error; int i, ntries; @@ -1985,7 +2039,7 @@ rum_init(struct rum_softc *sc) /* clear STA registers */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); - rum_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); + rum_set_macaddr(sc, IF_LLADDR(ifp)); /* initialize ASIC */ rum_write(sc, RT2573_MAC_CSR1, 4); @@ -2004,12 +2058,13 @@ rum_init(struct rum_softc *sc) RT2573_DROP_ACKCTS; if (ic->ic_opmode != IEEE80211_M_HOSTAP) tmp |= RT2573_DROP_TODS; - if (ic->ic_promisc == 0) + if (!(ifp->if_flags & IFF_PROMISC)) tmp |= RT2573_DROP_NOT_TO_ME; } rum_write(sc, RT2573_TXRX_CSR0, 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[RUM_BULK_WR]); usbd_transfer_start(sc->sc_xfer[RUM_BULK_RD]); return; @@ -2019,13 +2074,29 @@ fail: rum_stop(sc); } static void +rum_init(void *priv) +{ + struct rum_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + RUM_LOCK(sc); + rum_init_locked(sc); + RUM_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void rum_stop(struct rum_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; RUM_LOCK_ASSERT(sc, MA_OWNED); - sc->sc_running = 0; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); RUM_UNLOCK(sc); @@ -2117,23 +2188,27 @@ static int rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { - struct rum_softc *sc = ni->ni_ic->ic_softc; + struct ifnet *ifp = ni->ni_ic->ic_ifp; + struct rum_softc *sc = ifp->if_softc; RUM_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)) { RUM_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->tx_nfree < RUM_TX_MINFREE) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; RUM_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 @@ -2153,6 +2228,7 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); RUM_UNLOCK(sc); ieee80211_free_node(ni); return EIO; @@ -2186,7 +2262,8 @@ rum_ratectl_task(void *arg, int pending) struct rum_vap *rvp = arg; struct ieee80211vap *vap = &rvp->vap; struct ieee80211com *ic = vap->iv_ic; - struct rum_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rum_softc *sc = ifp->if_softc; struct ieee80211_node *ni; int ok, fail; int sum, retrycnt; @@ -2206,8 +2283,7 @@ rum_ratectl_task(void *arg, int pending) (void) ieee80211_ratectl_rate(ni, NULL, 0); ieee80211_free_node(ni); - /* 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(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp); RUM_UNLOCK(sc); @@ -2216,14 +2292,15 @@ rum_ratectl_task(void *arg, int pending) static void rum_scan_start(struct ieee80211com *ic) { - struct rum_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rum_softc *sc = ifp->if_softc; uint32_t tmp; RUM_LOCK(sc); /* abort TSF synchronization */ tmp = rum_read(sc, RT2573_TXRX_CSR9); rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); - rum_set_bssid(sc, ieee80211broadcastaddr); + rum_set_bssid(sc, ifp->if_broadcastaddr); RUM_UNLOCK(sc); } @@ -2231,11 +2308,11 @@ rum_scan_start(struct ieee80211com *ic) static void rum_scan_end(struct ieee80211com *ic) { - struct rum_softc *sc = ic->ic_softc; + struct rum_softc *sc = ic->ic_ifp->if_softc; RUM_LOCK(sc); rum_enable_tsf_sync(sc); - rum_set_bssid(sc, ic->ic_macaddr); + rum_set_bssid(sc, sc->sc_bssid); RUM_UNLOCK(sc); } @@ -2243,7 +2320,7 @@ rum_scan_end(struct ieee80211com *ic) static void rum_set_channel(struct ieee80211com *ic) { - struct rum_softc *sc = ic->ic_softc; + struct rum_softc *sc = ic->ic_ifp->if_softc; RUM_LOCK(sc); rum_set_chan(sc, ic->ic_curchan); @@ -2253,7 +2330,8 @@ rum_set_channel(struct ieee80211com *ic) static int rum_get_rssi(struct rum_softc *sc, uint8_t raw) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int lna, agc, rssi; lna = (raw >> 5) & 0x3; |