PERFORCE change 180844 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Jul 12 20:00:12 UTC 2010
http://p4web.freebsd.org/@@180844?ac=10
Change 180844 by hselasky at hselasky_laptop001 on 2010/07/12 19:59:47
USB WLAN:
- fix races by doing proper refcounting
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#29 edit
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_run.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_uath.c#22 edit
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_upgt.c#22 edit
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_ural.c#23 edit
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_urtw.c#16 edit
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_zyd.c#29 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#29 (text+ko) ====
@@ -709,9 +709,6 @@
IEEE80211_UNLOCK(ic);
- /* XXX temporary workaround for race in IEEE802.11 layer */
- usb_pause_mtx(NULL, hz / 16);
-
RUM_LOCK(sc);
usb_callout_stop(&rvp->ratectl_ch);
@@ -725,7 +722,7 @@
break;
case IEEE80211_S_RUN:
- ni = vap->iv_bss;
+ ni = ieee80211_ref_node(vap->iv_bss);
if (vap->iv_opmode != IEEE80211_M_MONITOR) {
rum_update_slot(ic->ic_ifp);
@@ -749,6 +746,8 @@
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
rum_ratectl_start(sc, ni);
+
+ ieee80211_free_node(ni);
break;
default:
break;
@@ -2229,7 +2228,7 @@
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = ic->ic_ifp;
struct rum_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
int ok, fail;
int sum, retrycnt;
@@ -2243,8 +2242,10 @@
sum = ok+fail;
retrycnt = (le32toh(sc->sta[5]) & 0xffff) + fail;
+ ni = ieee80211_ref_node(vap->iv_bss);
ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
(void) ieee80211_ratectl_rate(ni, NULL, 0);
+ ieee80211_free_node(ni);
ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_run.c#14 (text+ko) ====
@@ -1694,7 +1694,6 @@
struct ieee80211com *ic = vap->iv_ic;
const struct ieee80211_txparam *tp;
struct run_softc *sc = ic->ic_ifp->if_softc;
- struct run_node *rn = (void *)vap->iv_bss;
uint8_t rate, ridx;
int error;
@@ -1708,13 +1707,20 @@
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
+ struct ieee80211_node *ni;
+ struct run_node *rn;
+
rate = ic->ic_sup_rates[ic->ic_curmode].
rs_rates[tp->ucastrate] & IEEE80211_RATE_VAL;
for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
if (rt2860_rates[ridx].rate == rate)
break;
+
+ ni = ieee80211_ref_node(vap->iv_bss);
+ rn = (void *)ni;
rn->fix_ridx = ridx;
DPRINTF("rate=%d, fix_ridx=%d\n", rate, rn->fix_ridx);
+ ieee80211_free_node(ni);
}
#if 0
@@ -1782,7 +1788,8 @@
case IEEE80211_S_RUN:
- ni = vap->iv_bss;
+ ni = ieee80211_ref_node(vap->iv_bss);
+
if(!(sc->runbmap & bid)){
if(sc->running++)
restart_ratectl = 1;
@@ -1837,6 +1844,7 @@
(IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ?
RT2860_LED_LINK_2GHZ : RT2860_LED_LINK_5GHZ));
+ ieee80211_free_node(ni);
break;
default:
DPRINTFN(6, "undefined case\n");
@@ -1966,6 +1974,7 @@
ni = ieee80211_find_vap_node(&ic->ic_sta, vap, cmdq->mac);
else
ni = vap->iv_bss;
+
associd = (ni != NULL) ? ni->ni_associd : 0;
/* map net80211 cipher to RT2860 security mode */
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_uath.c#22 (text+ko) ====
@@ -1968,9 +1968,11 @@
const struct ieee80211_rateset *rs;
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
struct uath_cmd_create_connection create;
+ ni = ieee80211_ref_node(vap->iv_bss);
+
bzero(&create, sizeof create);
create.connid = htobe32(connid);
create.bssid = htobe32(0);
@@ -1990,6 +1992,8 @@
else
create.connattr.wlanmode = htobe32(WLAN_MODE_11b);
+ ieee80211_free_node(ni);
+
return uath_cmd_write(sc, WDCMSG_CREATE_CONNECTION, &create,
sizeof create, 0);
}
@@ -2017,14 +2021,19 @@
{
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
struct uath_cmd_set_associd associd;
+ ni = ieee80211_ref_node(vap->iv_bss);
+
bzero(&associd, sizeof associd);
associd.defaultrateix = htobe32(1); /* XXX */
associd.associd = htobe32(ni->ni_associd);
associd.timoffset = htobe32(0x3b); /* XXX */
IEEE80211_ADDR_COPY(associd.bssid, ni->ni_bssid);
+
+ ieee80211_free_node(ni);
+
return uath_cmd_write(sc, WDCMSG_WRITE_ASSOCID, &associd,
sizeof associd, 0);
}
@@ -2065,7 +2074,7 @@
{
enum ieee80211_state ostate = vap->iv_state;
int error;
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
struct ieee80211com *ic = vap->iv_ic;
struct uath_softc *sc = ic->ic_ifp->if_softc;
struct uath_vap *uvp = UATH_VAP(vap);
@@ -2076,9 +2085,6 @@
IEEE80211_UNLOCK(ic);
- /* XXX temporary workaround for race in IEEE802.11 layer */
- usb_pause_mtx(NULL, hz / 16);
-
UATH_LOCK(sc);
callout_stop(&sc->stat_ch);
callout_stop(&sc->watchdog_ch);
@@ -2095,32 +2101,44 @@
break;
case IEEE80211_S_AUTH:
+ ni = ieee80211_ref_node(vap->iv_bss);
+
/* XXX good place? set RTS threshold */
uath_config(sc, CFG_USER_RTS_THRESHOLD, vap->iv_rtsthreshold);
/* XXX bad place */
error = uath_set_keys(sc, vap);
if (error != 0) {
+ ieee80211_free_node(ni);
device_printf(sc->sc_dev,
"could not set crypto keys, error %d\n", error);
break;
}
if (uath_switch_channel(sc, ni->ni_chan) != 0) {
+ ieee80211_free_node(ni);
device_printf(sc->sc_dev, "could not switch channel\n");
break;
}
if (uath_create_connection(sc, UATH_ID_BSS) != 0) {
+ ieee80211_free_node(ni);
device_printf(sc->sc_dev,
"could not create connection\n");
break;
}
+
+ ieee80211_free_node(ni);
break;
case IEEE80211_S_ASSOC:
+ ni = ieee80211_ref_node(vap->iv_bss);
+
if (uath_set_rates(sc, &ni->ni_rates) != 0) {
+ ieee80211_free_node(ni);
device_printf(sc->sc_dev,
"could not set negotiated rate set\n");
break;
}
+
+ ieee80211_free_node(ni);
break;
case IEEE80211_S_RUN:
@@ -2130,6 +2148,8 @@
break;
}
+ ni = ieee80211_ref_node(vap->iv_bss);
+
/*
* Tx rate is controlled by firmware, report the maximum
* negotiated rate in ifconfig output.
@@ -2137,6 +2157,8 @@
ni->ni_txrate = ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates-1];
if (uath_write_associd(sc) != 0) {
+
+ ieee80211_free_node(ni);
device_printf(sc->sc_dev,
"could not write association id\n");
break;
@@ -2150,7 +2172,10 @@
/* start statistics timer */
callout_reset(&sc->stat_ch, hz, uath_stat, sc);
+
+ ieee80211_free_node(ni);
break;
+
default:
break;
}
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_upgt.c#22 (text+ko) ====
@@ -652,7 +652,7 @@
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
struct upgt_data *data_cmd;
struct upgt_lmac_mem *mem;
struct upgt_lmac_filter *filter;
@@ -707,6 +707,8 @@
filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
break;
case IEEE80211_S_RUN:
+ ni = ieee80211_ref_node(vap->iv_bss);
+
/* XXX monitor mode isn't tested yet. */
if (vap->iv_opmode == IEEE80211_M_MONITOR) {
filter->type = htole16(UPGT_FILTER_TYPE_MONITOR);
@@ -730,6 +732,8 @@
filter->rxhw = htole32(sc->sc_eeprom_hwrx);
filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
}
+
+ ieee80211_free_node(ni);
break;
default:
device_printf(sc->sc_dev,
@@ -1056,9 +1060,6 @@
IEEE80211_UNLOCK(ic);
- /* XXX temporary workaround for race in IEEE802.11 layer */
- usb_pause_mtx(NULL, hz / 16);
-
UPGT_LOCK(sc);
callout_stop(&sc->sc_led_ch);
callout_stop(&sc->sc_watchdog_ch);
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_ural.c#23 (text+ko) ====
@@ -695,9 +695,6 @@
IEEE80211_UNLOCK(ic);
- /* XXX temporary workaround for race in IEEE802.11 layer */
- usb_pause_mtx(NULL, hz / 16);
-
RAL_LOCK(sc);
usb_callout_stop(&uvp->ratectl_ch);
@@ -713,7 +710,7 @@
break;
case IEEE80211_S_RUN:
- ni = vap->iv_bss;
+ ni = ieee80211_ref_node(vap->iv_bss);
if (vap->iv_opmode != IEEE80211_M_MONITOR) {
ural_update_slot(ic->ic_ifp);
@@ -729,6 +726,7 @@
if (m == NULL) {
device_printf(sc->sc_dev,
"could not allocate beacon\n");
+ ieee80211_free_node(ni);
RAL_UNLOCK(sc);
IEEE80211_LOCK(ic);
return (-1);
@@ -737,6 +735,7 @@
if (ural_tx_bcn(sc, m, ni) != 0) {
device_printf(sc->sc_dev,
"could not send beacon\n");
+ ieee80211_free_node(ni);
RAL_UNLOCK(sc);
IEEE80211_LOCK(ic);
return (-1);
@@ -757,6 +756,7 @@
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
ural_ratectl_start(sc, ni);
+ ieee80211_free_node(ni);
break;
default:
@@ -2239,7 +2239,7 @@
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = ic->ic_ifp;
struct ural_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
int ok, fail;
int sum, retrycnt;
@@ -2253,8 +2253,10 @@
sum = ok+fail;
retrycnt = sc->sta[8] + fail;
+ ni = ieee80211_ref_node(vap->iv_bss);
ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
(void) ieee80211_ratectl_rate(ni, NULL, 0);
+ ieee80211_free_node(ni);
ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_urtw.c#16 (text+ko) ====
@@ -1830,7 +1830,7 @@
static int
urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
- struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_node *ni;
struct ieee80211com *ic = vap->iv_ic;
struct urtw_softc *sc = ic->ic_ifp->if_softc;
struct urtw_vap *uvp = URTW_VAP(vap);
@@ -1844,9 +1844,6 @@
IEEE80211_UNLOCK(ic);
- /* XXX temporary workaround for race in IEEE802.11 layer */
- usb_pause_mtx(NULL, hz / 16);
-
URTW_LOCK(sc);
usb_callout_stop(&sc->sc_led_ch);
callout_stop(&sc->sc_watchdog_ch);
@@ -1858,6 +1855,8 @@
case IEEE80211_S_ASSOC:
break;
case IEEE80211_S_RUN:
+ ni = ieee80211_ref_node(vap->iv_bss);
+
/* setting bssid. */
urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
urtw_write16_m(sc, URTW_BSSID + 4,
@@ -1872,6 +1871,8 @@
if (error != 0)
device_printf(sc->sc_dev,
"could not control LED (%d)\n", error);
+
+ ieee80211_free_node(ni);
break;
default:
break;
==== //depot/projects/usb/src/sys/dev/usb/wlan/if_zyd.c#29 (text+ko) ====
@@ -580,30 +580,34 @@
IEEE80211_UNLOCK(ic);
- /* XXX temporary workaround for race in IEEE802.11 layer */
- usb_pause_mtx(NULL, hz / 16);
-
ZYD_LOCK(sc);
switch (nstate) {
case IEEE80211_S_AUTH:
zyd_set_chan(sc, ic->ic_curchan);
break;
case IEEE80211_S_RUN:
- ni = vap->iv_bss;
- if (vap->iv_opmode == IEEE80211_M_MONITOR)
+ ni = ieee80211_ref_node(vap->iv_bss);
+ if (vap->iv_opmode == IEEE80211_M_MONITOR) {
+ ieee80211_free_node(ni);
break;
+ }
/* turn link LED on */
error = zyd_set_led(sc, ZYD_LED1, 1);
- if (error != 0)
+ if (error != 0) {
+ ieee80211_free_node(ni);
break;
+ }
/* make data LED blink upon Tx */
zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
zyd_set_bssid(sc, sc->sc_bssid);
+
+ ieee80211_free_node(ni);
break;
+
default:
break;
}
More information about the p4-projects
mailing list