From bad6d5c89b6ffd35818850d95cb88e218dee73b3 Mon Sep 17 00:00:00 2001 From: adrian Date: Sat, 8 Aug 2015 01:10:17 +0000 Subject: Revert the wifi ifnet changes until things are more baked and tested. * 286410 * 286413 * 286416 The initial commit broke a variety of debug and features that aren't in the GENERIC kernels but are enabled in other platforms. --- sys/dev/usb/wlan/if_run.c | 363 +++++++++++++++++++++++++++++----------------- 1 file changed, 226 insertions(+), 137 deletions(-) (limited to 'sys/dev/usb/wlan/if_run.c') diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index 193b9ad..ac14178 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -410,9 +410,8 @@ static int run_tx_param(struct run_softc *, struct mbuf *, const struct ieee80211_bpf_params *); static int run_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static int run_transmit(struct ieee80211com *, struct mbuf *); -static void run_start(struct run_softc *); -static void run_parent(struct ieee80211com *); +static void run_start(struct ifnet *); +static int run_ioctl(struct ifnet *, u_long, caddr_t); static void run_iq_calib(struct run_softc *, u_int); static void run_set_agc(struct run_softc *, uint8_t); static void run_select_chan_group(struct run_softc *, int); @@ -458,6 +457,7 @@ static void run_rt3593_rf_setup(struct run_softc *); static void run_rt5390_rf_setup(struct run_softc *); static int run_txrx_enable(struct run_softc *); static void run_adjust_freq_offset(struct run_softc *); +static void run_init(void *); static void run_init_locked(struct run_softc *); static void run_stop(void *); static void run_delay(struct run_softc *, u_int); @@ -702,7 +702,8 @@ run_attach(device_t self) { struct run_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; + struct ifnet *ifp; uint32_t ver; int ntries, error; uint8_t iface_index, bands; @@ -715,7 +716,6 @@ run_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF); - mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RT2860_IFACE_INDEX; @@ -754,10 +754,28 @@ run_attach(device_t self) device_printf(sc->sc_dev, "MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n", sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev), - sc->ntxchains, sc->nrxchains, ether_sprintf(ic->ic_macaddr)); + sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid)); RUN_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, "run", device_get_unit(sc->sc_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = run_init; + ifp->if_ioctl = run_ioctl; + ifp->if_start = run_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 */ @@ -794,7 +812,7 @@ run_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_scan_start = run_scan_start; ic->ic_scan_end = run_scan_end; @@ -806,10 +824,9 @@ run_attach(device_t self) ic->ic_wme.wme_update = run_wme_update; ic->ic_raw_xmit = run_raw_xmit; ic->ic_update_promisc = run_update_promisc; + ic->ic_vap_create = run_vap_create; ic->ic_vap_delete = run_vap_delete; - ic->ic_transmit = run_transmit; - ic->ic_parent = run_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -835,7 +852,8 @@ static int run_detach(device_t self) { struct run_softc *sc = device_get_softc(self); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic; int i; RUN_LOCK(sc); @@ -854,15 +872,16 @@ run_detach(device_t self) run_unsetup_tx_list(sc, &sc->sc_epq[i]); RUN_UNLOCK(sc); - if (sc->sc_ic.ic_softc == sc) { + if (ifp) { + ic = ifp->if_l2com; /* drain tasks */ usb_callout_drain(&sc->ratectl_ch); ieee80211_draintask(ic, &sc->cmdq_task); ieee80211_draintask(ic, &sc->ratectl_task); ieee80211_ifdetach(ic); + if_free(ifp); } - mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -874,13 +893,14 @@ run_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 run_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct run_softc *sc = ifp->if_softc; struct run_vap *rvp; struct ieee80211vap *vap; int i; if (sc->rvp_cnt >= RUN_VAP_MAX) { - device_printf(sc->sc_dev, "number of VAPs maxed out\n"); + if_printf(ifp, "number of VAPs maxed out\n"); return (NULL); } @@ -906,21 +926,23 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, break; } if (vap == NULL) { - device_printf(sc->sc_dev, - "wds only supported in ap mode\n"); + if_printf(ifp, "wds only supported in ap mode\n"); return (NULL); } break; default: - device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); + if_printf(ifp, "unknown opmode %d\n", opmode); return (NULL); } - rvp = malloc(sizeof(struct run_vap), M_80211_VAP, M_WAITOK | M_ZERO); + rvp = (struct run_vap *) malloc(sizeof(struct run_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return (NULL); vap = &rvp->vap; - if (ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, - bssid) != 0) { + if (ieee80211_vap_setup(ic, vap, name, unit, + opmode, flags, bssid, mac) != 0) { /* out of memory */ free(rvp, M_80211_VAP); return (NULL); @@ -947,8 +969,7 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); /* complete setup */ - ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status, - mac); + ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status); /* make sure id is always unique */ for (i = 0; i < RUN_VAP_MAX; i++) { @@ -974,6 +995,7 @@ static void run_vap_delete(struct ieee80211vap *vap) { struct run_vap *rvp = RUN_VAP(vap); + struct ifnet *ifp; struct ieee80211com *ic; struct run_softc *sc; uint8_t rvp_id; @@ -982,7 +1004,9 @@ run_vap_delete(struct ieee80211vap *vap) return; ic = vap->iv_ic; - sc = ic->ic_softc; + ifp = ic->ic_ifp; + + sc = ifp->if_softc; RUN_LOCK(sc); @@ -1716,7 +1740,6 @@ run_get_txpower(struct run_softc *sc) static int run_read_eeprom(struct run_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; int8_t delta_2ghz, delta_5ghz; uint32_t tmp; uint16_t val; @@ -1737,14 +1760,14 @@ run_read_eeprom(struct run_softc *sc) /* read MAC address */ run_srom_read(sc, RT2860_EEPROM_MAC01, &val); - ic->ic_macaddr[0] = val & 0xff; - ic->ic_macaddr[1] = val >> 8; + sc->sc_bssid[0] = val & 0xff; + sc->sc_bssid[1] = val >> 8; run_srom_read(sc, RT2860_EEPROM_MAC23, &val); - ic->ic_macaddr[2] = val & 0xff; - ic->ic_macaddr[3] = val >> 8; + sc->sc_bssid[2] = val & 0xff; + sc->sc_bssid[3] = val >> 8; run_srom_read(sc, RT2860_EEPROM_MAC45, &val); - ic->ic_macaddr[4] = val & 0xff; - ic->ic_macaddr[5] = val >> 8; + sc->sc_bssid[4] = val & 0xff; + sc->sc_bssid[5] = val >> 8; if (sc->mac_ver < 0x3593) { /* read vender BBP settings */ @@ -1979,7 +2002,7 @@ run_media_change(struct ifnet *ifp) struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; const struct ieee80211_txparam *tp; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; uint8_t rate, ridx; int error; @@ -2010,7 +2033,7 @@ run_media_change(struct ifnet *ifp) #if 0 if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & RUN_RUNNING)){ + (ifp->if_drv_flags & IFF_DRV_RUNNING)){ run_init_locked(sc); } #endif @@ -2025,7 +2048,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { const struct ieee80211_txparam *tp; struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; struct run_vap *rvp = RUN_VAP(vap); enum ieee80211_state ostate; uint32_t sta[3]; @@ -2121,7 +2144,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) run_set_txpreamble(sc); run_set_basicrates(sc); ni = ieee80211_ref_node(vap->iv_bss); - IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); run_set_bssid(sc, ni->ni_bssid); ieee80211_free_node(ni); run_enable_tsf_sync(sc); @@ -2158,7 +2181,7 @@ static void run_wme_update_cb(void *arg) { struct ieee80211com *ic = arg; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_wme_state *wmesp = &ic->ic_wme; int aci, error = 0; @@ -2211,7 +2234,7 @@ err: static int run_wme_update(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; /* sometime called wothout lock */ if (mtx_owned(&ic->ic_comlock.mtx)) { @@ -2254,7 +2277,7 @@ run_key_set_cb(void *arg) struct ieee80211vap *vap = cmdq->arg1; struct ieee80211_key *k = cmdq->k; struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_node *ni; uint32_t attr; uint16_t base, associd; @@ -2376,7 +2399,7 @@ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; uint32_t i; i = RUN_CMDQ_GET(&sc->cmdq_store); @@ -2444,7 +2467,7 @@ static int run_key_delete(struct ieee80211vap *vap, struct ieee80211_key *k) { struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_key *k0; uint32_t i; @@ -2475,7 +2498,7 @@ run_ratectl_to(void *arg) struct run_softc *sc = arg; /* do it in a process context, so it can go sleep */ - ieee80211_runtask(&sc->sc_ic, &sc->ratectl_task); + ieee80211_runtask(sc->sc_ifp->if_l2com, &sc->ratectl_task); /* next timeout will be rescheduled in the callback task */ } @@ -2484,7 +2507,7 @@ static void run_ratectl_cb(void *arg, int pending) { struct run_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); if (vap == NULL) @@ -2517,6 +2540,7 @@ static void run_drain_fifo(void *arg) { struct run_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t stat; uint16_t (*wstat)[3]; uint8_t wcid, mcs, pid; @@ -2553,7 +2577,7 @@ run_drain_fifo(void *arg) if (stat & RT2860_TXQ_OK) (*wstat)[RUN_SUCCESS]++; else - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* * Check if there were retries, ie if the Tx success rate is * different from the requested rate. Note that it works only @@ -2576,6 +2600,8 @@ run_iter_func(void *arg, struct ieee80211_node *ni) { struct run_softc *sc = arg; struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; struct run_node *rn = (void *)ni; union run_stats sta[2]; uint16_t (*wstat)[3]; @@ -2597,8 +2623,7 @@ run_iter_func(void *arg, struct ieee80211_node *ni) goto fail; /* count failed TX as errors */ - if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, - le16toh(sta[0].error.fail)); + if_inc_counter(ifp, IFCOUNTER_OERRORS, le16toh(sta[0].error.fail)); retrycnt = le16toh(sta[1].tx.retry); success = le16toh(sta[1].tx.success); @@ -2636,7 +2661,7 @@ run_newassoc_cb(void *arg) { struct run_cmdq *cmdq = arg; struct ieee80211_node *ni = cmdq->arg1; - struct run_softc *sc = ni->ni_vap->iv_ic->ic_softc; + struct run_softc *sc = ni->ni_vap->iv_ic->ic_ifp->if_softc; uint8_t wcid = cmdq->wcid; RUN_LOCK_ASSERT(sc, MA_OWNED); @@ -2654,7 +2679,7 @@ run_newassoc(struct ieee80211_node *ni, int isnew) struct ieee80211_rateset *rs = &ni->ni_rates; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; uint8_t rate; uint8_t ridx; uint8_t wcid; @@ -2744,7 +2769,8 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi) static void run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct rt2870_rxd *rxd; @@ -2763,7 +2789,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) rxwisize += sizeof(uint32_t); if (__predict_false(len > dmalen)) { m_freem(m); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF("bad RXWI length %u > %u\n", len, dmalen); return; } @@ -2773,7 +2799,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { m_freem(m); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV"); return; } @@ -2802,7 +2828,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) ieee80211_notify_michael_failure(ni->ni_vap, wh, rxwi->keyidx); m_freem(m); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF("MIC error. Someone is lying.\n"); return; } @@ -2811,6 +2837,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) rssi = rxwi->rssi[ant]; nf = run_rssi2dbm(sc, rssi, ant); + m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = len; if (ni != NULL) { @@ -2863,7 +2890,7 @@ static void run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct run_softc *sc = usbd_xfer_softc(xfer); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; struct mbuf *m = NULL; struct mbuf *m0; uint32_t dmalen; @@ -2901,7 +2928,7 @@ tr_setup: } if (sc->rx_m == NULL) { DPRINTF("could not allocate mbuf - idle with stall\n"); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); usbd_xfer_set_stall(xfer); usbd_xfer_set_frames(xfer, 0); } else { @@ -2921,9 +2948,12 @@ tr_setup: if (error != USB_ERR_CANCELLED) { /* try to clear stall first */ usbd_xfer_set_stall(xfer); + if (error == USB_ERR_TIMEOUT) device_printf(sc->sc_dev, "device timeout\n"); - counter_u64_add(ic->ic_ierrors, 1); + + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + goto tr_setup; } if (sc->rx_m != NULL) { @@ -2971,7 +3001,7 @@ tr_setup: m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m0 == NULL)) { DPRINTF("could not allocate mbuf\n"); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); break; } m_copydata(m, 4 /* skip 32-bit DMA-len header */, @@ -3018,7 +3048,8 @@ static void run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) { struct run_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 run_tx_data *data; struct ieee80211vap *vap = NULL; struct usb_page_cache *pc; @@ -3036,9 +3067,14 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) "bytes @ index %d\n", actlen, index); data = usbd_xfer_get_priv(xfer); + run_tx_free(pq, data, 0); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + usbd_xfer_set_priv(xfer, NULL); + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -3055,7 +3091,11 @@ tr_setup: size + 3 + 8) > RUN_MAX_TXSZ) { DPRINTF("data overflow, %u bytes\n", m->m_pkthdr.len); + + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + run_tx_free(pq, data, 1); + goto tr_setup; } @@ -3092,8 +3132,12 @@ tr_setup: usbd_xfer_set_frame_len(xfer, 0, size); usbd_xfer_set_priv(xfer, data); + usbd_transfer_submit(xfer); - run_start(sc); + + RUN_UNLOCK(sc); + run_start(ifp); + RUN_LOCK(sc); break; @@ -3103,13 +3147,14 @@ tr_setup: data = usbd_xfer_get_priv(xfer); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if (data != NULL) { if(data->ni != NULL) vap = data->ni->ni_vap; run_tx_free(pq, data, error); usbd_xfer_set_priv(xfer, NULL); } - if (vap == NULL) vap = TAILQ_FIRST(&ic->ic_vaps); @@ -3175,7 +3220,7 @@ static void run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data) { struct mbuf *m = data->m; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = data->ni->ni_vap; struct ieee80211_frame *wh; struct rt2870_txd *txd; @@ -3238,7 +3283,7 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data) static int run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ieee80211_channel *chan; @@ -3406,7 +3451,8 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) static int run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct run_node *rn = (void *)ni; struct run_tx_data *data; struct ieee80211_frame *wh; @@ -3437,9 +3483,11 @@ run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) USETW(wh->i_dur, dur); } - if (sc->sc_epq[0].tx_nfree == 0) + if (sc->sc_epq[0].tx_nfree == 0) { /* let caller free mbuf */ + ifp->if_drv_flags |= IFF_DRV_OACTIVE; return (EIO); + } data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh); STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next); sc->sc_epq[0].tx_nfree--; @@ -3507,9 +3555,11 @@ run_sendprot(struct run_softc *sc, wflags = RT2860_TX_FRAG; /* check that there are free slots before allocating the mbuf */ - if (sc->sc_epq[0].tx_nfree == 0) + if (sc->sc_epq[0].tx_nfree == 0) { /* let caller free mbuf */ + sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; return (ENOBUFS); + } if (prot == IEEE80211_PROT_RTSCTS) { /* NB: CTS is the same size as an ACK */ @@ -3520,7 +3570,7 @@ run_sendprot(struct run_softc *sc, mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); } if (mprot == NULL) { - if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); DPRINTF("could not allocate mbuf\n"); return (ENOBUFS); } @@ -3602,6 +3652,7 @@ run_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni, if (sc->sc_epq[0].tx_nfree == 0) { /* let caller free mbuf */ + sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; DPRINTF("sending raw frame, but tx ring is full\n"); return (EIO); } @@ -3640,31 +3691,36 @@ static int run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { - struct run_softc *sc = ni->ni_ic->ic_softc; + struct ifnet *ifp = ni->ni_ic->ic_ifp; + struct run_softc *sc = ifp->if_softc; int error = 0; RUN_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(sc->sc_flags & RUN_RUNNING)) { - error = ENETDOWN; + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + error = ENETDOWN; goto done; } if (params == NULL) { /* tx mgt packet */ if ((error = run_tx_mgt(sc, m, ni)) != 0) { + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); DPRINTF("mgt tx failed\n"); goto done; } } else { /* tx raw packet with param */ if ((error = run_tx_param(sc, m, ni, params)) != 0) { + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); DPRINTF("tx with param failed\n"); goto done; } } + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + done: RUN_UNLOCK(sc); @@ -3677,71 +3733,83 @@ done: return (error); } -static int -run_transmit(struct ieee80211com *ic, struct mbuf *m) -{ - struct run_softc *sc = ic->ic_softc; - int error; - - RUN_LOCK(sc); - if ((sc->sc_flags & RUN_RUNNING) == 0) { - RUN_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - RUN_UNLOCK(sc); - return (error); - } - run_start(sc); - RUN_UNLOCK(sc); - - return (0); -} - static void -run_start(struct run_softc *sc) +run_start(struct ifnet *ifp) { + struct run_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - RUN_LOCK_ASSERT(sc, MA_OWNED); + RUN_LOCK(sc); - if ((sc->sc_flags & RUN_RUNNING) == 0) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + RUN_UNLOCK(sc); return; + } + + for (;;) { + /* send data frames */ + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; - while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (run_tx(sc, m, ni) != 0) { - mbufq_prepend(&sc->sc_snd, m); + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } } + + RUN_UNLOCK(sc); } -static void -run_parent(struct ieee80211com *ic) +static int +run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ifp->if_softc; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; int startall = 0; + int error; RUN_LOCK(sc); - if (sc->sc_detached) { + error = sc->sc_detached ? ENXIO : 0; + RUN_UNLOCK(sc); + if (error) + return (error); + + switch (cmd) { + case SIOCSIFFLAGS: + RUN_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)){ + startall = 1; + run_init_locked(sc); + } else + run_update_promisc_locked(sc); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING && + (ic->ic_nrunning == 0 || sc->rvp_cnt <= 1)) { + run_stop(sc); + } + } RUN_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_flags & RUN_RUNNING)) { - startall = 1; - run_init_locked(sc); - } else - run_update_promisc_locked(sc); - } else if ((sc->sc_flags & RUN_RUNNING) && sc->rvp_cnt <= 1) - run_stop(sc); - RUN_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + return (error); } static void @@ -4728,7 +4796,7 @@ run_set_rx_antenna(struct run_softc *sc, int aux) static int run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; u_int chan, group; chan = ieee80211_chan2ieee(ic, c); @@ -4773,7 +4841,7 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) static void run_set_channel(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; RUN_LOCK(sc); run_set_chan(sc, ic->ic_curchan); @@ -4785,7 +4853,7 @@ run_set_channel(struct ieee80211com *ic) static void run_scan_start(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; uint32_t tmp; RUN_LOCK(sc); @@ -4795,7 +4863,7 @@ run_scan_start(struct ieee80211com *ic) run_write(sc, RT2860_BCN_TIME_CFG, tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN)); - run_set_bssid(sc, ieee80211broadcastaddr); + run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr); RUN_UNLOCK(sc); @@ -4805,13 +4873,13 @@ run_scan_start(struct ieee80211com *ic) static void run_scan_end(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; RUN_LOCK(sc); run_enable_tsf_sync(sc); /* XXX keep local copy */ - run_set_bssid(sc, ic->ic_macaddr); + run_set_bssid(sc, sc->sc_bssid); RUN_UNLOCK(sc); @@ -4826,7 +4894,7 @@ static void run_update_beacon(struct ieee80211vap *vap, int item) { struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; struct run_vap *rvp = RUN_VAP(vap); int mcast = 0; uint32_t i; @@ -4871,7 +4939,7 @@ run_update_beacon_cb(void *arg) struct ieee80211vap *vap = arg; struct run_vap *rvp = RUN_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; struct rt2860_txwi txwi; struct mbuf *m; uint16_t txwisize; @@ -4919,7 +4987,7 @@ run_update_beacon_cb(void *arg) static void run_updateprot(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; uint32_t i; i = RUN_CMDQ_GET(&sc->cmdq_store); @@ -4933,7 +5001,7 @@ static void run_updateprot_cb(void *arg) { struct ieee80211com *ic = arg; - struct run_softc *sc = ic->ic_softc; + struct run_softc *sc = ic->ic_ifp->if_softc; uint32_t tmp; tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; @@ -4957,7 +5025,7 @@ static void run_usb_timeout_cb(void *arg) { struct ieee80211vap *vap = arg; - struct run_softc *sc = vap->iv_ic->ic_softc; + struct run_softc *sc = vap->iv_ic->ic_ifp->if_softc; RUN_LOCK_ASSERT(sc, MA_OWNED); @@ -5003,12 +5071,12 @@ run_update_promisc_locked(struct run_softc *sc) run_read(sc, RT2860_RX_FILTR_CFG, &tmp); tmp |= RT2860_DROP_UC_NOME; - if (sc->sc_ic.ic_promisc > 0) + if (sc->sc_ifp->if_flags & IFF_PROMISC) tmp &= ~RT2860_DROP_UC_NOME; run_write(sc, RT2860_RX_FILTR_CFG, tmp); - DPRINTF("%s promiscuous mode\n", (sc->sc_ic.ic_promisc > 0) ? + DPRINTF("%s promiscuous mode\n", (sc->sc_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); } @@ -5017,7 +5085,7 @@ run_update_promisc(struct ieee80211com *ic) { struct run_softc *sc = ic->ic_softc; - if ((sc->sc_flags & RUN_RUNNING) == 0) + if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; RUN_LOCK(sc); @@ -5028,7 +5096,7 @@ run_update_promisc(struct ieee80211com *ic) static void run_enable_tsf_sync(struct run_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; @@ -5093,7 +5161,7 @@ run_enable_mrr(struct run_softc *sc) static void run_set_txpreamble(struct run_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; uint32_t tmp; run_read(sc, RT2860_AUTO_RSP_CFG, &tmp); @@ -5107,7 +5175,7 @@ run_set_txpreamble(struct run_softc *sc) static void run_set_basicrates(struct run_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; /* set basic rates mask */ if (ic->ic_curmode == IEEE80211_MODE_11B) @@ -5152,7 +5220,7 @@ run_updateslot(struct ieee80211com *ic) i = RUN_CMDQ_GET(&sc->cmdq_store); DPRINTF("cmdq_store=%d\n", i); sc->cmdq[i].func = run_updateslot_cb; - sc->cmdq[i].arg0 = ic; + sc->cmdq[i].arg0 = ic->ic_ifp; ieee80211_runtask(ic, &sc->cmdq_task); return; @@ -5162,8 +5230,9 @@ run_updateslot(struct ieee80211com *ic) static void run_updateslot_cb(void *arg) { - struct ieee80211com *ic = arg; - struct run_softc *sc = ic->ic_softc; + struct ifnet *ifp = arg; + struct run_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp); @@ -5175,12 +5244,15 @@ run_updateslot_cb(void *arg) static void run_update_mcast(struct ieee80211com *ic) { + + /* h/w filter supports getting everything or nothing */ + ic->ic_ifp->if_flags |= IFF_ALLMULTI; } static int8_t run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211_channel *c = ic->ic_curchan; int delta; @@ -5830,7 +5902,7 @@ run_rt5390_rf_setup(struct run_softc *sc) static int run_txrx_enable(struct run_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; uint32_t tmp; int error, ntries; @@ -5890,8 +5962,8 @@ run_adjust_freq_offset(struct run_softc *sc) static void run_init_locked(struct run_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; uint8_t bbp1, bbp3; int i; @@ -5921,7 +5993,7 @@ run_init_locked(struct run_softc *sc) for (i = 0; i != RUN_EP_QUEUES; i++) run_setup_tx_list(sc, &sc->sc_epq[i]); - run_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); + run_set_macaddr(sc, IF_LLADDR(ifp)); for (ntries = 0; ntries < 100; ntries++) { if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0) @@ -6094,7 +6166,8 @@ run_init_locked(struct run_softc *sc) /* turn radio LED on */ run_set_leds(sc, RT2860_LED_RADIO); - sc->sc_flags |= RUN_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; sc->cmdq_run = RUN_CMDQ_GO; for (i = 0; i != RUN_N_XFER; i++) @@ -6112,19 +6185,35 @@ fail: } static void +run_init(void *arg) +{ + struct run_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + RUN_LOCK(sc); + run_init_locked(sc); + RUN_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); +} + +static void run_stop(void *arg) { struct run_softc *sc = (struct run_softc *)arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int i; int ntries; RUN_LOCK_ASSERT(sc, MA_OWNED); - if (sc->sc_flags & RUN_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) run_set_leds(sc, 0); /* turn all LEDs off */ - sc->sc_flags &= ~RUN_RUNNING; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); sc->ratectl_run = RUN_RATECTL_OFF; sc->cmdq_run = sc->cmdq_key_set; -- cgit v1.1