summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2010-09-02 03:28:03 +0000
committerthompsa <thompsa@FreeBSD.org>2010-09-02 03:28:03 +0000
commit1a84f8ba2ae2f9c4b0376b200c9e1c505ea1f6e5 (patch)
tree96181ac569fa147859c67d6e8334673d021645fe /sys/dev
parent5621f791d2277c43041de7701e15cbcfa9b6dd87 (diff)
downloadFreeBSD-src-1a84f8ba2ae2f9c4b0376b200c9e1c505ea1f6e5.zip
FreeBSD-src-1a84f8ba2ae2f9c4b0376b200c9e1c505ea1f6e5.tar.gz
We need to grab a node reference count to vap->iv_bss before using it as it is
possible for the node to be replaced and freed at any time by ieee80211_sta_join1().
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/wlan/if_rum.c7
-rw-r--r--sys/dev/usb/wlan/if_run.c13
-rw-r--r--sys/dev/usb/wlan/if_uath.c12
-rw-r--r--sys/dev/usb/wlan/if_upgt.c5
-rw-r--r--sys/dev/usb/wlan/if_ural.c10
-rw-r--r--sys/dev/usb/wlan/if_urtw.c5
-rw-r--r--sys/dev/usb/wlan/if_zyd.c4
7 files changed, 40 insertions, 16 deletions
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index 26993cd..d3cb788 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -719,7 +719,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
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);
@@ -743,6 +743,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
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;
@@ -2223,7 +2224,7 @@ rum_ratectl_task(void *arg, int pending)
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;
@@ -2237,8 +2238,10 @@ rum_ratectl_task(void *arg, int pending)
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 */
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 6c9afb9..d6cbf3a 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -1693,7 +1693,6 @@ run_media_change(struct ifnet *ifp)
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;
@@ -1707,13 +1706,19 @@ run_media_change(struct ifnet *ifp)
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 = (struct run_node *)ni;
rn->fix_ridx = ridx;
DPRINTF("rate=%d, fix_ridx=%d\n", rate, rn->fix_ridx);
+ ieee80211_free_node(ni);
}
#if 0
@@ -1736,7 +1741,6 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
struct run_softc *sc = ic->ic_ifp->if_softc;
struct run_vap *rvp = RUN_VAP(vap);
enum ieee80211_state ostate;
- struct ieee80211_node *ni;
uint32_t sta[3];
uint32_t tmp;
uint8_t ratectl;
@@ -1781,7 +1785,6 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
case IEEE80211_S_RUN:
- ni = vap->iv_bss;
if (!(sc->runbmap & bid)) {
if(sc->running++)
restart_ratectl = 1;
@@ -1817,12 +1820,16 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
}
if (vap->iv_opmode != IEEE80211_M_MONITOR) {
+ struct ieee80211_node *ni;
+
run_updateslot(ic->ic_ifp);
run_enable_mrr(sc);
run_set_txpreamble(sc);
run_set_basicrates(sc);
+ ni = ieee80211_ref_node(vap->iv_bss);
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);
/* enable automatic rate adaptation */
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index a2fba42..35202a9 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -1968,9 +1968,10 @@ uath_create_connection(struct uath_softc *sc, uint32_t connid)
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);
@@ -1989,6 +1990,7 @@ uath_create_connection(struct uath_softc *sc, uint32_t connid)
create.connattr.wlanmode = htobe32(WLAN_MODE_11g);
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 +2019,16 @@ uath_write_associd(struct uath_softc *sc)
{
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 +2069,7 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
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);
@@ -2078,6 +2082,7 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
UATH_LOCK(sc);
callout_stop(&sc->stat_ch);
callout_stop(&sc->watchdog_ch);
+ ni = ieee80211_ref_node(vap->iv_bss);
switch (nstate) {
case IEEE80211_S_INIT:
@@ -2150,6 +2155,7 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
default:
break;
}
+ ieee80211_free_node(ni);
UATH_UNLOCK(sc);
IEEE80211_LOCK(ic);
return (uvp->newstate(vap, nstate, arg));
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index 58d7162..73f7e1e 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -652,7 +652,6 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
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 upgt_data *data_cmd;
struct upgt_lmac_mem *mem;
struct upgt_lmac_filter *filter;
@@ -707,6 +706,9 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
break;
case IEEE80211_S_RUN:
+ struct ieee80211_node *ni;
+
+ 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,7 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
filter->rxhw = htole32(sc->sc_eeprom_hwrx);
filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
}
+ ieee80211_free_node(ni);
break;
default:
device_printf(sc->sc_dev,
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 94b560d..aa2dcbd 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -711,7 +711,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
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 +729,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
"could not allocate beacon\n");
RAL_UNLOCK(sc);
IEEE80211_LOCK(ic);
+ ieee80211_free_node(ni);
return (-1);
}
ieee80211_ref_node(ni);
@@ -737,6 +738,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
"could not send beacon\n");
RAL_UNLOCK(sc);
IEEE80211_LOCK(ic);
+ ieee80211_free_node(ni);
return (-1);
}
}
@@ -754,7 +756,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
ural_ratectl_start(sc, ni);
-
+ ieee80211_free_node(ni);
break;
default:
@@ -2237,10 +2239,11 @@ ural_ratectl_task(void *arg, int pending)
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;
+ ni = ieee80211_ref_node(vap->iv_bss);
RAL_LOCK(sc);
/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta));
@@ -2258,6 +2261,7 @@ ural_ratectl_task(void *arg, int pending)
usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
RAL_UNLOCK(sc);
+ ieee80211_free_node(ni);
}
static int
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index 39f1847..0236956 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -1830,7 +1830,6 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
static int
urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
- struct ieee80211_node *ni = vap->iv_bss;
struct ieee80211com *ic = vap->iv_ic;
struct urtw_softc *sc = ic->ic_ifp->if_softc;
struct urtw_vap *uvp = URTW_VAP(vap);
@@ -1854,6 +1853,9 @@ urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
case IEEE80211_S_ASSOC:
break;
case IEEE80211_S_RUN:
+ struct ieee80211_node *ni;
+
+ 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,
@@ -1868,6 +1870,7 @@ urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
if (error != 0)
device_printf(sc->sc_dev,
"could not control LED (%d)\n", error);
+ ieee80211_free_node(ni);
break;
default:
break;
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 6415cd4..e8d7b7e 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -572,7 +572,6 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
struct zyd_vap *zvp = ZYD_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
struct zyd_softc *sc = ic->ic_ifp->if_softc;
- struct ieee80211_node *ni;
int error;
DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
@@ -586,7 +585,6 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
zyd_set_chan(sc, ic->ic_curchan);
break;
case IEEE80211_S_RUN:
- ni = vap->iv_bss;
if (vap->iv_opmode == IEEE80211_M_MONITOR)
break;
@@ -598,7 +596,7 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* 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);
+ IEEE80211_ADDR_COPY(sc->sc_bssid, vap->iv_bss->ni_bssid);
zyd_set_bssid(sc, sc->sc_bssid);
break;
default:
OpenPOWER on IntegriCloud