Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net80211/ieee80211_scan_sw.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
#define ROAM_RATE_11B_DEFAULT 2*5 /* 11b bss */ | #define ROAM_RATE_11B_DEFAULT 2*5 /* 11b bss */ | ||||
#define ROAM_RATE_11BONLY_DEFAULT 2*1 /* 11b-only bss */ | #define ROAM_RATE_11BONLY_DEFAULT 2*1 /* 11b-only bss */ | ||||
#define ROAM_RATE_HALF_DEFAULT 2*6 /* half-width 11a/g bss */ | #define ROAM_RATE_HALF_DEFAULT 2*6 /* half-width 11a/g bss */ | ||||
#define ROAM_RATE_QUARTER_DEFAULT 2*3 /* quarter-width 11a/g bss */ | #define ROAM_RATE_QUARTER_DEFAULT 2*3 /* quarter-width 11a/g bss */ | ||||
#define ROAM_MCS_11N_DEFAULT (1 | IEEE80211_RATE_MCS) /* 11n bss */ | #define ROAM_MCS_11N_DEFAULT (1 | IEEE80211_RATE_MCS) /* 11n bss */ | ||||
static void scan_curchan(struct ieee80211_scan_state *, unsigned long); | static void scan_curchan(struct ieee80211_scan_state *, unsigned long); | ||||
static void scan_mindwell(struct ieee80211_scan_state *); | static void scan_mindwell(struct ieee80211_scan_state *); | ||||
static void scan_signal(void *); | static void scan_signal(struct ieee80211_scan_state *, int); | ||||
static void scan_signal_locked(struct ieee80211_scan_state *, int); | |||||
static void scan_start(void *, int); | static void scan_start(void *, int); | ||||
static void scan_curchan_task(void *, int); | static void scan_curchan_task(void *, int); | ||||
static void scan_end(struct ieee80211_scan_state *, int); | static void scan_end(struct ieee80211_scan_state *, int); | ||||
static void scan_done(struct ieee80211_scan_state *, int); | static void scan_done(struct ieee80211_scan_state *, int); | ||||
MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state"); | MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state"); | ||||
static void | static void | ||||
ieee80211_swscan_detach(struct ieee80211com *ic) | ieee80211_swscan_detach(struct ieee80211com *ic) | ||||
{ | { | ||||
struct ieee80211_scan_state *ss = ic->ic_scan; | struct ieee80211_scan_state *ss = ic->ic_scan; | ||||
if (ss != NULL) { | if (ss != NULL) { | ||||
IEEE80211_LOCK(ic); | scan_signal(ss, ISCAN_ABORT); | ||||
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; | |||||
scan_signal(ss); | |||||
IEEE80211_UNLOCK(ic); | |||||
ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start); | ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start); | ||||
taskqueue_drain_timeout(ic->ic_tq, | taskqueue_drain_timeout(ic->ic_tq, | ||||
&SCAN_PRIVATE(ss)->ss_scan_curchan); | &SCAN_PRIVATE(ss)->ss_scan_curchan); | ||||
KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, | KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, | ||||
("scan still running")); | ("scan still running")); | ||||
/* | /* | ||||
* For now, do the ss_ops detach here rather | * For now, do the ss_ops detach here rather | ||||
Show All 25 Lines | |||||
ieee80211_swscan_vdetach(struct ieee80211vap *vap) | ieee80211_swscan_vdetach(struct ieee80211vap *vap) | ||||
{ | { | ||||
struct ieee80211com *ic = vap->iv_ic; | struct ieee80211com *ic = vap->iv_ic; | ||||
struct ieee80211_scan_state *ss; | struct ieee80211_scan_state *ss; | ||||
IEEE80211_LOCK_ASSERT(ic); | IEEE80211_LOCK_ASSERT(ic); | ||||
ss = ic->ic_scan; | ss = ic->ic_scan; | ||||
if (ss != NULL && ss->ss_vap == vap) { | if (ss != NULL && ss->ss_vap == vap) { | ||||
if (ic->ic_flags & IEEE80211_F_SCAN) { | if (ic->ic_flags & IEEE80211_F_SCAN) | ||||
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; | scan_signal_locked(ss, ISCAN_ABORT); | ||||
scan_signal(ss); | |||||
} | } | ||||
} | } | ||||
} | |||||
static void | static void | ||||
ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration) | ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration) | ||||
{ | { | ||||
struct ieee80211com *ic = vap->iv_ic; | struct ieee80211com *ic = vap->iv_ic; | ||||
struct ieee80211_scan_state *ss = ic->ic_scan; | struct ieee80211_scan_state *ss = ic->ic_scan; | ||||
IEEE80211_LOCK_ASSERT(ic); | IEEE80211_LOCK_ASSERT(ic); | ||||
▲ Show 20 Lines • Show All 267 Lines • ▼ Show 20 Lines | cancel_scan(struct ieee80211vap *vap, int any, const char *func) | ||||
if ((ic->ic_flags & IEEE80211_F_SCAN) && | if ((ic->ic_flags & IEEE80211_F_SCAN) && | ||||
(any || ss->ss_vap == vap) && | (any || ss->ss_vap == vap) && | ||||
(SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) { | (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) == 0) { | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: cancel %s scan\n", func, | "%s: cancel %s scan\n", func, | ||||
ss->ss_flags & IEEE80211_SCAN_ACTIVE ? | ss->ss_flags & IEEE80211_SCAN_ACTIVE ? | ||||
"active" : "passive"); | "active" : "passive"); | ||||
/* clear bg scan NOPICK and mark cancel request */ | /* clear bg scan NOPICK */ | ||||
ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; | ss->ss_flags &= ~IEEE80211_SCAN_NOPICK; | ||||
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL; | /* mark cancel request and wake up the scan task */ | ||||
/* wake up the scan task */ | scan_signal_locked(ss, ISCAN_CANCEL); | ||||
scan_signal(ss); | |||||
} else { | } else { | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n", | "%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n", | ||||
func, | func, | ||||
!! (ic->ic_flags & IEEE80211_F_SCAN), | !! (ic->ic_flags & IEEE80211_F_SCAN), | ||||
(ss->ss_vap == vap ? "match" : "nomatch"), | (ss->ss_vap == vap ? "match" : "nomatch"), | ||||
!! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL)); | !! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL)); | ||||
} | } | ||||
Show All 20 Lines | |||||
/* | /* | ||||
* Public access to scan_next for drivers that manage | * Public access to scan_next for drivers that manage | ||||
* scanning themselves (e.g. for firmware-based devices). | * scanning themselves (e.g. for firmware-based devices). | ||||
*/ | */ | ||||
static void | static void | ||||
ieee80211_swscan_scan_next(struct ieee80211vap *vap) | ieee80211_swscan_scan_next(struct ieee80211vap *vap) | ||||
{ | { | ||||
struct ieee80211com *ic = vap->iv_ic; | struct ieee80211_scan_state *ss = vap->iv_ic->ic_scan; | ||||
struct ieee80211_scan_state *ss = ic->ic_scan; | |||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); | ||||
/* wake up the scan task */ | /* wake up the scan task */ | ||||
IEEE80211_LOCK(ic); | scan_signal(ss, 0); | ||||
scan_signal(ss); | |||||
IEEE80211_UNLOCK(ic); | |||||
} | } | ||||
/* | /* | ||||
* Public access to scan_next for drivers that are not able to scan single | * Public access to scan_next for drivers that are not able to scan single | ||||
* channels (e.g. for firmware-based devices). | * channels (e.g. for firmware-based devices). | ||||
*/ | */ | ||||
static void | static void | ||||
ieee80211_swscan_scan_done(struct ieee80211vap *vap) | ieee80211_swscan_scan_done(struct ieee80211vap *vap) | ||||
{ | { | ||||
struct ieee80211com *ic = vap->iv_ic; | struct ieee80211com *ic = vap->iv_ic; | ||||
struct ieee80211_scan_state *ss; | struct ieee80211_scan_state *ss; | ||||
IEEE80211_LOCK_ASSERT(ic); | IEEE80211_LOCK_ASSERT(ic); | ||||
ss = ic->ic_scan; | ss = ic->ic_scan; | ||||
scan_signal(ss); | scan_signal_locked(ss, 0); | ||||
} | } | ||||
/* | /* | ||||
* Probe the curent channel, if allowed, while scanning. | * Probe the curent channel, if allowed, while scanning. | ||||
* If the channel is not marked passive-only then send | * If the channel is not marked passive-only then send | ||||
* a probe request immediately. Otherwise mark state and | * a probe request immediately. Otherwise mark state and | ||||
* listen for beacons on the channel; if we receive something | * listen for beacons on the channel; if we receive something | ||||
* then we'll transmit a probe request. | * then we'll transmit a probe request. | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) | ||||
if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) | if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) | ||||
ieee80211_probe_curchan(vap, 0); | ieee80211_probe_curchan(vap, 0); | ||||
taskqueue_enqueue_timeout(vap->iv_ic->ic_tq, | taskqueue_enqueue_timeout(vap->iv_ic->ic_tq, | ||||
&SCAN_PRIVATE(ss)->ss_scan_curchan, maxdwell); | &SCAN_PRIVATE(ss)->ss_scan_curchan, maxdwell); | ||||
IEEE80211_UNLOCK(vap->iv_ic); | IEEE80211_UNLOCK(vap->iv_ic); | ||||
} | } | ||||
static void | static void | ||||
scan_signal(void *arg) | scan_signal(struct ieee80211_scan_state *ss, int iflags) | ||||
{ | { | ||||
struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg; | struct ieee80211com *ic = ss->ss_ic; | ||||
IEEE80211_UNLOCK_ASSERT(ic); | |||||
IEEE80211_LOCK(ic); | |||||
scan_signal_locked(ss, iflags); | |||||
IEEE80211_UNLOCK(ic); | |||||
} | |||||
static void | |||||
scan_signal_locked(struct ieee80211_scan_state *ss, int iflags) | |||||
{ | |||||
struct scan_state *ss_priv = SCAN_PRIVATE(ss); | struct scan_state *ss_priv = SCAN_PRIVATE(ss); | ||||
struct timeout_task *scan_task = &ss_priv->ss_scan_curchan; | struct timeout_task *scan_task = &ss_priv->ss_scan_curchan; | ||||
struct ieee80211com *ic = ss->ss_ic; | struct ieee80211com *ic = ss->ss_ic; | ||||
IEEE80211_LOCK_ASSERT(ic); | IEEE80211_LOCK_ASSERT(ic); | ||||
ss_priv->ss_iflags |= iflags; | |||||
if (ss_priv->ss_iflags & ISCAN_RUNNING) { | if (ss_priv->ss_iflags & ISCAN_RUNNING) { | ||||
if (taskqueue_cancel_timeout(ic->ic_tq, scan_task, NULL) == 0) | if (taskqueue_cancel_timeout(ic->ic_tq, scan_task, NULL) == 0) | ||||
taskqueue_enqueue_timeout(ic->ic_tq, scan_task, 0); | taskqueue_enqueue_timeout(ic->ic_tq, scan_task, 0); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Handle mindwell requirements completed; initiate a channel | * Handle mindwell requirements completed; initiate a channel | ||||
* change to the next channel asap. | * change to the next channel asap. | ||||
*/ | */ | ||||
static void | static void | ||||
scan_mindwell(struct ieee80211_scan_state *ss) | scan_mindwell(struct ieee80211_scan_state *ss) | ||||
{ | { | ||||
struct ieee80211com *ic = ss->ss_ic; | struct ieee80211vap *vap = ss->ss_vap; | ||||
IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); | ||||
IEEE80211_LOCK(ic); | scan_signal(ss, 0); | ||||
scan_signal(ss); | |||||
IEEE80211_UNLOCK(ic); | |||||
} | } | ||||
static void | static void | ||||
scan_start(void *arg, int pending) | scan_start(void *arg, int pending) | ||||
{ | { | ||||
#define ISCAN_REP (ISCAN_MINDWELL | ISCAN_DISCARD) | #define ISCAN_REP (ISCAN_MINDWELL | ISCAN_DISCARD) | ||||
struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg; | struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg; | ||||
struct scan_state *ss_priv = SCAN_PRIVATE(ss); | struct scan_state *ss_priv = SCAN_PRIVATE(ss); | ||||
▲ Show 20 Lines • Show All 379 Lines • Show Last 20 Lines |