Date: Fri, 14 Mar 2008 05:31:19 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 137688 for review Message-ID: <200803140531.m2E5VJDM096971@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=137688 Change 137688 by sam@sam_ebb on 2008/03/14 05:30:19 o reorder code in detach to avoid teardown races o track amrr changes o fix scanning so scan stop restores the previous bssid w/o touching the bss node as that may change concurrently o replace callout thread for amrr work by inline calls to ieee80211_amrr_choose on xmit o replace IFQ_POLL/IFQ_DEQUEUE by deq/prepend on q full; this is not right but makes the driver consistent with the other usb drivers so we can fix 'em all at once Affected files ... .. //depot/projects/vap/sys/dev/usb/if_zyd.c#10 edit .. //depot/projects/vap/sys/dev/usb/if_zydreg.h#6 edit Differences ... ==== //depot/projects/vap/sys/dev/usb/if_zyd.c#10 (text+ko) ==== @@ -65,10 +65,7 @@ #include <dev/usb/if_zydreg.h> #include <dev/usb/if_zydfw.h> -#ifdef USB_DEBUG #define ZYD_DEBUG -#endif - #ifdef ZYD_DEBUG #define DPRINTF(x) do { if (zyddebug > 0) printf x; } while (0) #define DPRINTFN(n, x) do { if (zyddebug > (n)) printf x; } while (0) @@ -228,8 +225,6 @@ static void zyd_init(void *); static void zyd_stop(struct zyd_softc *, int); static int zyd_loadfirmware(struct zyd_softc *, u_char *, size_t); -static void zyd_iter_func(void *, struct ieee80211_node *); -static void zyd_amrr_timeout(void *); static void zyd_newassoc(struct ieee80211_node *, int); static void zyd_scantask(void *); static void zyd_scan_start(struct ieee80211com *); @@ -384,6 +379,8 @@ sc->fw_rev >> 8, sc->fw_rev & 0xff, zyd_rf_name(sc->rf_rev), sc->pa_rev, ether_sprintf(ic->ic_myaddr)); + IEEE80211_ADDR_COPY(sc->sc_bssid, ic->ic_myaddr); + ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ ic->ic_opmode = IEEE80211_M_STA; @@ -451,16 +448,16 @@ ifp->if_flags &= ~IFF_UP; zyd_stop(sc, 1); + bpfdetach(ifp); + ieee80211_ifdetach(ic); + usb_rem_task(sc->sc_udev, &sc->sc_scantask); usb_rem_task(sc->sc_udev, &sc->sc_task); callout_stop(&sc->sc_watchdog_ch); zyd_close_pipes(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); if_free(ifp); - mtx_destroy(&sc->sc_mtx); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); @@ -492,10 +489,10 @@ zvp->newstate = vap->iv_newstate; vap->iv_newstate = zyd_newstate; - callout_init(&zvp->amrr_ch, 0); ieee80211_amrr_init(&zvp->amrr, vap, IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 1000 /* 1 sec */); /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); @@ -508,7 +505,7 @@ { struct zyd_vap *zvp = ZYD_VAP(vap); - callout_stop(&zvp->amrr_ch); + ieee80211_amrr_cleanup(&zvp->amrr); ieee80211_vap_detach(vap); free(zvp, M_80211_VAP); } @@ -719,7 +716,6 @@ case IEEE80211_S_RUN: { struct ieee80211_node *ni = vap->iv_bss; - const struct ieee80211_txparam *tp; zyd_set_chan(sc, ic->ic_curchan); @@ -730,19 +726,14 @@ /* make data LED blink upon Tx */ zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 1); - zyd_set_bssid(sc, ni->ni_bssid); + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + zyd_set_bssid(sc, sc->sc_bssid); } if (vap->iv_opmode == IEEE80211_M_STA) { /* fake a join to init the tx rate */ zyd_newassoc(ni, 1); } - - /* start automatic rate control timer */ - tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; - if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) - callout_reset(&zvp->amrr_ch, hz, zyd_amrr_timeout, vap); - break; } default: @@ -751,6 +742,11 @@ IEEE80211_LOCK(ic); /*XXX*/ zvp->newstate(vap, sc->sc_state, sc->sc_arg); + if (sc->sc_state == IEEE80211_S_RUN) { + /* XXX compensate for deferred handling of newstate */ + vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + if_start(vap->iv_ifp); + } IEEE80211_UNLOCK(ic); } @@ -762,7 +758,6 @@ struct zyd_softc *sc = ic->ic_ifp->if_softc; usb_rem_task(sc->sc_udev, &sc->sc_task); - callout_stop(&zvp->amrr_ch); /* do it in a process context */ sc->sc_state = nstate; @@ -1902,7 +1897,8 @@ */ ni = ieee80211_find_txnode(vap, retry->macaddr); if (ni != NULL) { - ZYD_NODE(ni)->amn.amn_retrycnt++; + ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, + IEEE80211_AMRR_FAILURE, 1); ieee80211_free_node(ni); } if (le16toh(retry->count) & 0x100) @@ -2230,7 +2226,8 @@ ni = data->ni; /* update rate control statistics */ - ZYD_NODE(ni)->amn.amn_txcnt++; + ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, + IEEE80211_AMRR_SUCCESS, 0); /* * Do any tx complete callback. Note this must @@ -2278,11 +2275,12 @@ if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { rate = tp->mcastrate; desc->flags |= ZYD_TX_FLAG_MULTICAST; - } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { rate = tp->ucastrate; - else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - rate &= IEEE80211_RATE_VAL; + } else { + (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn); + rate = ni->ni_txrate; + } if (wh->i_fc[1] & IEEE80211_FC1_WEP) { k = ieee80211_crypto_encap(ni, m0); @@ -2385,14 +2383,14 @@ struct mbuf *m; for (;;) { - IFQ_POLL(&ifp->if_snd, m); + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; if (sc->tx_queued >= ZYD_TX_LIST_CNT) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } - IFQ_DEQUEUE(&ifp->if_snd, m); ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m = ieee80211_encap(ni, m); if (m == NULL) { @@ -2686,44 +2684,11 @@ } static void -zyd_iter_func(void *arg, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct zyd_node *zn = (struct zyd_node *)ni; - - ieee80211_amrr_choose(&ZYD_VAP(vap)->amrr, ni, &zn->amn); -} - -static void -zyd_amrr_timeout(void *arg) -{ - struct ieee80211vap *vap = arg; - struct ieee80211com *ic = vap->iv_ic; - struct zyd_softc *sc = ic->ic_ifp->if_softc; - - ZYD_LOCK(sc); - if (vap->iv_opmode == IEEE80211_M_STA) - zyd_iter_func(sc, vap->iv_bss); - else - ieee80211_iterate_nodes(&ic->ic_sta, zyd_iter_func, sc); - ZYD_UNLOCK(sc); - - callout_reset(&ZYD_VAP(vap)->amrr_ch, hz, zyd_amrr_timeout, vap); -} - -static void zyd_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211vap *vap = ni->ni_vap; - int i; - ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn); - - /* set rate to some reasonable initial value */ - for (i = ni->ni_rates.rs_nrates - 1; - i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; - i--); - ni->ni_txrate = i; + ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni); } static void @@ -2767,18 +2732,19 @@ { struct zyd_softc *sc = arg; struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ifnet *ifp = ic->ic_ifp; ZYD_LOCK(sc); switch (sc->sc_scan_action) { case ZYD_SCAN_START: + /* want broadcast address while scanning */ zyd_set_bssid(sc, ifp->if_broadcastaddr); break; case ZYD_SCAN_END: - zyd_set_bssid(sc, vap->iv_bss->ni_bssid); + /* restore previous bssid */ + zyd_set_bssid(sc, sc->sc_bssid); break; case ZYD_SET_CHANNEL: ==== //depot/projects/vap/sys/dev/usb/if_zydreg.h#6 (text+ko) ==== @@ -1200,7 +1200,7 @@ int sc_flags; int sc_if_flags; #define ZD1211_FWLOADED (1 << 0) - + uint8_t sc_bssid[IEEE80211_ADDR_LEN]; enum ieee80211_state sc_state; int sc_arg;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803140531.m2E5VJDM096971>