PERFORCE change 137688 for review
Sam Leffler
sam at FreeBSD.org
Fri Mar 14 05:31:20 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=137688
Change 137688 by sam at 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;
More information about the p4-projects
mailing list