Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net80211/ieee80211_scan_sw.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
struct scan_state { | struct scan_state { | ||||
struct ieee80211_scan_state base; /* public state */ | struct ieee80211_scan_state base; /* public state */ | ||||
u_int ss_iflags; /* flags used internally */ | u_int ss_iflags; /* flags used internally */ | ||||
#define ISCAN_MINDWELL 0x0001 /* min dwell time reached */ | #define ISCAN_MINDWELL 0x0001 /* min dwell time reached */ | ||||
#define ISCAN_DISCARD 0x0002 /* discard rx'd frames */ | #define ISCAN_DISCARD 0x0002 /* discard rx'd frames */ | ||||
#define ISCAN_CANCEL 0x0004 /* cancel current scan */ | #define ISCAN_CANCEL 0x0004 /* cancel current scan */ | ||||
#define ISCAN_ABORT 0x0008 /* end the scan immediately */ | #define ISCAN_ABORT 0x0008 /* end the scan immediately */ | ||||
#define ISCAN_RUNNING 0x0010 /* scan was started */ | |||||
unsigned long ss_chanmindwell; /* min dwell on curchan */ | unsigned long ss_chanmindwell; /* min dwell on curchan */ | ||||
unsigned long ss_scanend; /* time scan must stop */ | unsigned long ss_scanend; /* time scan must stop */ | ||||
u_int ss_duration; /* duration for next scan */ | u_int ss_duration; /* duration for next scan */ | ||||
struct task ss_scan_task; /* scan execution */ | struct task ss_scan_start; /* scan start */ | ||||
struct cv ss_scan_cv; /* scan signal */ | struct timeout_task ss_scan_curchan; /* scan execution */ | ||||
struct callout ss_scan_timer; /* scan timer */ | |||||
}; | }; | ||||
#define SCAN_PRIVATE(ss) ((struct scan_state *) ss) | #define SCAN_PRIVATE(ss) ((struct scan_state *) ss) | ||||
/* | /* | ||||
* Amount of time to go off-channel during a background | * Amount of time to go off-channel during a background | ||||
* scan. This value should be large enough to catch most | * scan. This value should be large enough to catch most | ||||
* ap's but short enough that we can return on-channel | * ap's but short enough that we can return on-channel | ||||
* before our listen interval expires. | * before our listen interval expires. | ||||
Show All 18 Lines | |||||
#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(void *); | ||||
static void scan_task(void *, int); | static void scan_start(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); | IEEE80211_LOCK(ic); | ||||
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; | SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_ABORT; | ||||
scan_signal(ss); | scan_signal(ss); | ||||
IEEE80211_UNLOCK(ic); | IEEE80211_UNLOCK(ic); | ||||
ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); | ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start); | ||||
callout_drain(&SCAN_PRIVATE(ss)->ss_scan_timer); | taskqueue_drain_timeout(ic->ic_tq, | ||||
&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 | ||||
* than ieee80211_scan_detach(). | * than ieee80211_scan_detach(). | ||||
* | * | ||||
* I'll figure out how to cleanly split things up | * I'll figure out how to cleanly split things up | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | if (ss->ss_ops != NULL) { | ||||
ss->ss_ops->scan_start(ss, vap); | ss->ss_ops->scan_start(ss, vap); | ||||
#ifdef IEEE80211_DEBUG | #ifdef IEEE80211_DEBUG | ||||
if (ieee80211_msg_scan(vap)) | if (ieee80211_msg_scan(vap)) | ||||
ieee80211_scan_dump(ss); | ieee80211_scan_dump(ss); | ||||
#endif /* IEEE80211_DEBUG */ | #endif /* IEEE80211_DEBUG */ | ||||
ic->ic_flags |= IEEE80211_F_SCAN; | ic->ic_flags |= IEEE80211_F_SCAN; | ||||
/* Start scan task */ | /* Start scan task */ | ||||
ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); | ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_start); | ||||
} | } | ||||
return 1; | return 1; | ||||
} else { | } else { | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: %s scan already in progress\n", __func__, | "%s: %s scan already in progress\n", __func__, | ||||
ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"); | ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"); | ||||
} | } | ||||
return 0; | return 0; | ||||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | #ifdef IEEE80211_DEBUG | ||||
ieee80211_scan_dump(ss); | ieee80211_scan_dump(ss); | ||||
#endif /* IEEE80211_DEBUG */ | #endif /* IEEE80211_DEBUG */ | ||||
} | } | ||||
} | } | ||||
ieee80211_swscan_set_scan_duration(vap, duration); | ieee80211_swscan_set_scan_duration(vap, duration); | ||||
ss->ss_maxdwell = duration; | ss->ss_maxdwell = duration; | ||||
ic->ic_flags |= IEEE80211_F_SCAN; | ic->ic_flags |= IEEE80211_F_SCAN; | ||||
ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN; | ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN; | ||||
ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task); | ieee80211_runtask(ic, | ||||
&SCAN_PRIVATE(ss)->ss_scan_start); | |||||
} else { | } else { | ||||
/* XXX msg+stat */ | /* XXX msg+stat */ | ||||
} | } | ||||
} else { | } else { | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: %s scan already in progress\n", __func__, | "%s: %s scan already in progress\n", __func__, | ||||
ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"); | ss->ss_flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: calling; maxdwell=%lu\n", | "%s: calling; maxdwell=%lu\n", | ||||
__func__, | __func__, | ||||
maxdwell); | maxdwell); | ||||
IEEE80211_LOCK(vap->iv_ic); | IEEE80211_LOCK(vap->iv_ic); | ||||
if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) | if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) | ||||
ieee80211_probe_curchan(vap, 0); | ieee80211_probe_curchan(vap, 0); | ||||
callout_reset(&SCAN_PRIVATE(ss)->ss_scan_timer, | taskqueue_enqueue_timeout(vap->iv_ic->ic_tq, | ||||
maxdwell, scan_signal, ss); | &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(void *arg) | ||||
{ | { | ||||
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 timeout_task *scan_task = &ss_priv->ss_scan_curchan; | |||||
struct ieee80211com *ic = ss->ss_ic; | |||||
IEEE80211_LOCK_ASSERT(ss->ss_ic); | IEEE80211_LOCK_ASSERT(ic); | ||||
cv_signal(&SCAN_PRIVATE(ss)->ss_scan_cv); | |||||
if (ss_priv->ss_iflags & ISCAN_RUNNING) { | |||||
if (taskqueue_cancel_timeout(ic->ic_tq, scan_task, NULL) == 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 ieee80211com *ic = ss->ss_ic; | ||||
IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); | IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); | ||||
IEEE80211_LOCK(ic); | IEEE80211_LOCK(ic); | ||||
scan_signal(ss); | scan_signal(ss); | ||||
IEEE80211_UNLOCK(ic); | IEEE80211_UNLOCK(ic); | ||||
} | } | ||||
static void | static void | ||||
scan_task(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); | ||||
struct ieee80211vap *vap = ss->ss_vap; | struct ieee80211vap *vap = ss->ss_vap; | ||||
struct ieee80211com *ic = ss->ss_ic; | struct ieee80211com *ic = ss->ss_ic; | ||||
struct ieee80211_channel *chan; | |||||
unsigned long maxdwell; | |||||
int scandone = 0; | |||||
IEEE80211_LOCK(ic); | IEEE80211_LOCK(ic); | ||||
if (vap == NULL || (ic->ic_flags & IEEE80211_F_SCAN) == 0 || | if (vap == NULL || (ic->ic_flags & IEEE80211_F_SCAN) == 0 || | ||||
(ss_priv->ss_iflags & ISCAN_ABORT)) { | (ss_priv->ss_iflags & ISCAN_ABORT)) { | ||||
/* Cancelled before we started */ | /* Cancelled before we started */ | ||||
scan_done(ss, 0); | scan_done(ss, 0); | ||||
return; | return; | ||||
} | } | ||||
Show All 10 Lines | if (vap->iv_opmode == IEEE80211_M_STA && | ||||
if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) { | if ((vap->iv_bss->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) { | ||||
/* Enable station power save mode */ | /* Enable station power save mode */ | ||||
vap->iv_sta_ps(vap, 1); | vap->iv_sta_ps(vap, 1); | ||||
/* | /* | ||||
* Use an 1ms delay so the null data frame has a chance | * Use an 1ms delay so the null data frame has a chance | ||||
* to go out. | * to go out. | ||||
* XXX Should use M_TXCB mechanism to eliminate this. | * XXX Should use M_TXCB mechanism to eliminate this. | ||||
*/ | */ | ||||
cv_timedwait(&ss_priv->ss_scan_cv, | mtx_sleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH, | ||||
IEEE80211_LOCK_OBJ(ic), msecs_to_ticks(1)); | "sta_ps", msecs_to_ticks(1)); | ||||
if (ss_priv->ss_iflags & ISCAN_ABORT) { | if (ss_priv->ss_iflags & ISCAN_ABORT) { | ||||
scan_done(ss, 0); | scan_done(ss, 0); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
ss_priv->ss_scanend = ticks + ss_priv->ss_duration; | ss_priv->ss_scanend = ticks + ss_priv->ss_duration; | ||||
/* XXX scan state can change! Re-validate scan state! */ | /* XXX scan state can change! Re-validate scan state! */ | ||||
IEEE80211_UNLOCK(ic); | IEEE80211_UNLOCK(ic); | ||||
ic->ic_scan_start(ic); /* notify driver */ | ic->ic_scan_start(ic); /* notify driver */ | ||||
IEEE80211_LOCK(ic); | |||||
for (;;) { | scan_curchan_task(ss, 0); | ||||
} | |||||
static void | |||||
scan_curchan_task(void *arg, int pending) | |||||
{ | |||||
struct ieee80211_scan_state *ss = arg; | |||||
struct scan_state *ss_priv = SCAN_PRIVATE(ss); | |||||
struct ieee80211vap *vap = ss->ss_vap; | |||||
struct ieee80211com *ic = ss->ss_ic; | |||||
struct ieee80211_channel *chan; | |||||
unsigned long maxdwell; | |||||
int scandone; | |||||
IEEE80211_LOCK(ic); | |||||
end: | |||||
scandone = (ss->ss_next >= ss->ss_last) || | scandone = (ss->ss_next >= ss->ss_last) || | ||||
(ss_priv->ss_iflags & ISCAN_CANCEL) != 0; | (ss_priv->ss_iflags & ISCAN_CANCEL) != 0; | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: loop start; scandone=%d\n", | "%s: loop start; scandone=%d\n", | ||||
__func__, | __func__, | ||||
scandone); | scandone); | ||||
if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) || | if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) || | ||||
(ss_priv->ss_iflags & ISCAN_ABORT) || | (ss_priv->ss_iflags & ISCAN_ABORT) || | ||||
time_after(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) { | time_after(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) { | ||||
ss_priv->ss_iflags &= ~ISCAN_RUNNING; | |||||
scan_end(ss, scandone); | scan_end(ss, scandone); | ||||
return; | return; | ||||
} | } else | ||||
ss_priv->ss_iflags |= ISCAN_RUNNING; | |||||
chan = ss->ss_chans[ss->ss_next++]; | chan = ss->ss_chans[ss->ss_next++]; | ||||
/* | /* | ||||
* Watch for truncation due to the scan end time. | * Watch for truncation due to the scan end time. | ||||
*/ | */ | ||||
if (time_after(ticks + ss->ss_maxdwell, ss_priv->ss_scanend)) | if (time_after(ticks + ss->ss_maxdwell, ss_priv->ss_scanend)) | ||||
maxdwell = ss_priv->ss_scanend - ticks; | maxdwell = ss_priv->ss_scanend - ticks; | ||||
else | else | ||||
maxdwell = ss->ss_maxdwell; | maxdwell = ss->ss_maxdwell; | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n", | "%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n", | ||||
__func__, | __func__, | ||||
ieee80211_chan2ieee(ic, ic->ic_curchan), | ieee80211_chan2ieee(ic, ic->ic_curchan), | ||||
ieee80211_channel_type_char(ic->ic_curchan), | ieee80211_channel_type_char(ic->ic_curchan), | ||||
ieee80211_chan2ieee(ic, chan), | ieee80211_chan2ieee(ic, chan), | ||||
ieee80211_channel_type_char(chan), | ieee80211_channel_type_char(chan), | ||||
(ss->ss_flags & IEEE80211_SCAN_ACTIVE) && | (ss->ss_flags & IEEE80211_SCAN_ACTIVE) && | ||||
(chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 ? | (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 ? | ||||
"active" : "passive", | "active" : "passive", | ||||
ticks_to_msecs(ss->ss_mindwell), ticks_to_msecs(maxdwell)); | ticks_to_msecs(ss->ss_mindwell), ticks_to_msecs(maxdwell)); | ||||
/* | /* | ||||
* Potentially change channel and phy mode. | * Potentially change channel and phy mode. | ||||
*/ | */ | ||||
ic->ic_curchan = chan; | ic->ic_curchan = chan; | ||||
ic->ic_rt = ieee80211_get_ratetable(chan); | ic->ic_rt = ieee80211_get_ratetable(chan); | ||||
IEEE80211_UNLOCK(ic); | IEEE80211_UNLOCK(ic); | ||||
/* | /* | ||||
* Perform the channel change and scan unlocked so the driver | * Perform the channel change and scan unlocked so the driver | ||||
* may sleep. Once set_channel returns the hardware has | * may sleep. Once set_channel returns the hardware has | ||||
* completed the channel change. | * completed the channel change. | ||||
*/ | */ | ||||
ic->ic_set_channel(ic); | ic->ic_set_channel(ic); | ||||
ieee80211_radiotap_chan_change(ic); | ieee80211_radiotap_chan_change(ic); | ||||
/* | /* | ||||
* Scan curchan. Drivers for "intelligent hardware" | * Scan curchan. Drivers for "intelligent hardware" | ||||
* override ic_scan_curchan to tell the device to do | * override ic_scan_curchan to tell the device to do | ||||
* the work. Otherwise we manage the work outselves; | * the work. Otherwise we manage the work ourselves; | ||||
* sending a probe request (as needed), and arming the | * sending a probe request (as needed), and arming the | ||||
* timeout to switch channels after maxdwell ticks. | * timeout to switch channels after maxdwell ticks. | ||||
* | * | ||||
* scan_curchan should only pause for the time required to | * scan_curchan should only pause for the time required to | ||||
* prepare/initiate the hardware for the scan (if at all), the | * prepare/initiate the hardware for the scan (if at all). | ||||
* below condvar is used to sleep for the channels dwell time | |||||
* and allows it to be signalled for abort. | |||||
*/ | */ | ||||
ic->ic_scan_curchan(ss, maxdwell); | ic->ic_scan_curchan(ss, maxdwell); | ||||
IEEE80211_LOCK(ic); | IEEE80211_LOCK(ic); | ||||
/* XXX scan state can change! Re-validate scan state! */ | /* XXX scan state can change! Re-validate scan state! */ | ||||
ss_priv->ss_chanmindwell = ticks + ss->ss_mindwell; | ss_priv->ss_chanmindwell = ticks + ss->ss_mindwell; | ||||
/* clear mindwell lock and initial channel change flush */ | /* clear mindwell lock and initial channel change flush */ | ||||
ss_priv->ss_iflags &= ~ISCAN_REP; | ss_priv->ss_iflags &= ~ISCAN_REP; | ||||
if (ss_priv->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT)) | if (ss_priv->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT)) | ||||
continue; | goto end; | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: waiting\n", __func__); | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: waiting\n", __func__); | ||||
/* Wait to be signalled to scan the next channel */ | IEEE80211_UNLOCK(ic); | ||||
cv_wait(&ss_priv->ss_scan_cv, IEEE80211_LOCK_OBJ(ic)); | |||||
} | } | ||||
} | |||||
static void | static void | ||||
scan_end(struct ieee80211_scan_state *ss, int scandone) | scan_end(struct ieee80211_scan_state *ss, int scandone) | ||||
{ | { | ||||
struct scan_state *ss_priv = SCAN_PRIVATE(ss); | struct scan_state *ss_priv = SCAN_PRIVATE(ss); | ||||
struct ieee80211vap *vap = ss->ss_vap; | struct ieee80211vap *vap = ss->ss_vap; | ||||
struct ieee80211com *ic = ss->ss_ic; | struct ieee80211com *ic = ss->ss_ic; | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
ticks, ss->ss_mindwell, ss_priv->ss_scanend); | ticks, ss->ss_mindwell, ss_priv->ss_scanend); | ||||
ss->ss_next = 0; /* reset to begining */ | ss->ss_next = 0; /* reset to begining */ | ||||
if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) | if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) | ||||
vap->iv_stats.is_scan_active++; | vap->iv_stats.is_scan_active++; | ||||
else | else | ||||
vap->iv_stats.is_scan_passive++; | vap->iv_stats.is_scan_passive++; | ||||
ss->ss_ops->scan_restart(ss, vap); /* XXX? */ | ss->ss_ops->scan_restart(ss, vap); /* XXX? */ | ||||
ieee80211_runtask(ic, &ss_priv->ss_scan_task); | ieee80211_runtask(ic, &ss_priv->ss_scan_start); | ||||
IEEE80211_UNLOCK(ic); | IEEE80211_UNLOCK(ic); | ||||
return; | return; | ||||
} | } | ||||
/* past here, scandone is ``true'' if not in bg mode */ | /* past here, scandone is ``true'' if not in bg mode */ | ||||
if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0) | if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0) | ||||
scandone = 1; | scandone = 1; | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | ieee80211_swscan_attach(struct ieee80211com *ic) | ||||
/* Allocate initial scan state */ | /* Allocate initial scan state */ | ||||
ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state), | ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state), | ||||
M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); | M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); | ||||
if (ss == NULL) { | if (ss == NULL) { | ||||
ic->ic_scan = NULL; | ic->ic_scan = NULL; | ||||
return; | return; | ||||
} | } | ||||
callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0); | TASK_INIT(&ss->ss_scan_start, 0, scan_start, ss); | ||||
cv_init(&ss->ss_scan_cv, "scan"); | TIMEOUT_TASK_INIT(ic->ic_tq, &ss->ss_scan_curchan, 0, | ||||
TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss); | scan_curchan_task, ss); | ||||
ic->ic_scan = &ss->base; | ic->ic_scan = &ss->base; | ||||
ss->base.ss_ic = ic; | ss->base.ss_ic = ic; | ||||
ic->ic_scan_curchan = scan_curchan; | ic->ic_scan_curchan = scan_curchan; | ||||
ic->ic_scan_mindwell = scan_mindwell; | ic->ic_scan_mindwell = scan_mindwell; | ||||
} | } |