Index: ieee80211_sta.c =================================================================== --- ieee80211_sta.c (revision 362465) +++ ieee80211_sta.c (working copy) @@ -291,7 +291,7 @@ * in iv_scanreq. Otherwise we do the default. */ if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { - ieee80211_check_scan(vap, + ieee80211_check_scan_locked(vap, vap->iv_scanreq_flags, vap->iv_scanreq_duration, vap->iv_scanreq_mindwell, @@ -299,7 +299,7 @@ vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; } else - ieee80211_check_scan_current(vap); + ieee80211_check_scan_current_locked(vap); break; case IEEE80211_S_SCAN: case IEEE80211_S_AUTH: Index: ieee80211_scan.c =================================================================== --- ieee80211_scan.c (revision 362465) +++ ieee80211_scan.c (working copy) @@ -404,7 +404,62 @@ return (result); } + /* + * Variant of above where IC is already locked. + */ +int +ieee80211_check_scan(struct ieee80211vap *vap, int flags, + u_int duration, u_int mindwell, u_int maxdwell, + u_int nssid, const struct ieee80211_scan_ssid ssids[]) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_scan_state *ss = ic->ic_scan; + const struct ieee80211_scanner *scan; + int result; + + scan = ieee80211_scanner_get(vap->iv_opmode); + if (scan == NULL) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: no scanner support for %s mode\n", + __func__, vap->iv_opmode); + /* XXX stat */ + return 0; + } + + /* + * Check if there's a list of scan candidates already. + * XXX want more than the ap we're currently associated with + */ + + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: %s scan, %s%s%s%s%s\n" + , __func__ + , flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive" + , flags & IEEE80211_SCAN_FLUSH ? "flush" : "append" + , flags & IEEE80211_SCAN_NOPICK ? ", nopick" : "" + , flags & IEEE80211_SCAN_NOJOIN ? ", nojoin" : "" + , flags & IEEE80211_SCAN_PICK1ST ? ", pick1st" : "" + , flags & IEEE80211_SCAN_ONCE ? ", once" : "" + ); + + if (ss->ss_ops != scan) { + /* XXX re-use cache contents? e.g. adhoc<->sta */ + flags |= IEEE80211_SCAN_FLUSH; + } + + /* + * XXX TODO: separate things out a bit better. + */ + ieee80211_scan_update_locked(vap, scan); + + result = ic->ic_scan_methods->sc_check_scan(scan, vap, flags, duration, + mindwell, maxdwell, nssid, ssids); + + return (result); +} + +/* * Check the scan cache for an ap/channel to use; if that fails * then kick off a scan using the current settings. */ @@ -418,6 +473,18 @@ } /* + * Variant of above where IC is already locked. + */ +int +ieee80211_check_scan_current_locked(struct ieee80211vap *vap) +{ + return ieee80211_check_scan_locked(vap, + IEEE80211_SCAN_ACTIVE, + IEEE80211_SCAN_FOREVER, 0, 0, + vap->iv_des_nssid, vap->iv_des_ssid); +} + +/* * Restart a previous scan. If the previous scan completed * then we start again using the existing channel list. */ Index: ieee80211_scan.h =================================================================== --- ieee80211_scan.h (revision 362465) +++ ieee80211_scan.h (working copy) @@ -172,7 +172,11 @@ int ieee80211_check_scan(struct ieee80211vap *, int flags, u_int duration, u_int mindwell, u_int maxdwell, u_int nssid, const struct ieee80211_scan_ssid ssids[]); +int ieee80211_check_scan_locked(struct ieee80211vap *, int flags, + u_int duration, u_int mindwell, u_int maxdwell, + u_int nssid, const struct ieee80211_scan_ssid ssids[]); int ieee80211_check_scan_current(struct ieee80211vap *); +int ieee80211_check_scan_current_locked(struct ieee80211vap *); int ieee80211_bg_scan(struct ieee80211vap *, int); void ieee80211_cancel_scan(struct ieee80211vap *); void ieee80211_cancel_anyscan(struct ieee80211vap *);