summaryrefslogtreecommitdiffstats
path: root/sys/dev/ath/if_ath.c
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-03-02 02:57:10 +0000
committeradrian <adrian@FreeBSD.org>2012-03-02 02:57:10 +0000
commit9d9d3e6003bbc132c6ea5089cf960ea566d26e9f (patch)
treeb9a55dd40ea0863f8b12d352acf491d24a29a491 /sys/dev/ath/if_ath.c
parent8aaa665509e9b3c1ef98710a57fdfff323336625 (diff)
downloadFreeBSD-src-9d9d3e6003bbc132c6ea5089cf960ea566d26e9f.zip
FreeBSD-src-9d9d3e6003bbc132c6ea5089cf960ea566d26e9f.tar.gz
Wrap the scan code state change stuff behind ATH_LOCK and the PCU fiddling
behind the PCU lock. sc_scanning is being checked without ATH_LOCK behind held and could in theory run from multiple threads.
Diffstat (limited to 'sys/dev/ath/if_ath.c')
-rw-r--r--sys/dev/ath/if_ath.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index c6556cb..1b02f6a 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -5637,11 +5637,16 @@ ath_scan_start(struct ieee80211com *ic)
/* XXX calibration timer? */
+ ATH_LOCK(sc);
sc->sc_scanning = 1;
sc->sc_syncbeacon = 0;
rfilt = ath_calcrxfilter(sc);
+ ATH_UNLOCK(sc);
+
+ ATH_PCU_LOCK(sc);
ath_hal_setrxfilter(ah, rfilt);
ath_hal_setassocid(ah, ifp->if_broadcastaddr, 0);
+ ATH_PCU_UNLOCK(sc);
DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0\n",
__func__, rfilt, ether_sprintf(ifp->if_broadcastaddr));
@@ -5655,12 +5660,17 @@ ath_scan_end(struct ieee80211com *ic)
struct ath_hal *ah = sc->sc_ah;
u_int32_t rfilt;
+ ATH_LOCK(sc);
sc->sc_scanning = 0;
rfilt = ath_calcrxfilter(sc);
+ ATH_UNLOCK(sc);
+
+ ATH_PCU_LOCK(sc);
ath_hal_setrxfilter(ah, rfilt);
ath_hal_setassocid(ah, sc->sc_curbssid, sc->sc_curaid);
ath_hal_process_noisefloor(ah);
+ ATH_PCU_UNLOCK(sc);
DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0x%x\n",
__func__, rfilt, ether_sprintf(sc->sc_curbssid),
OpenPOWER on IntegriCloud