Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net80211/ieee80211_scan_sw.c
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
#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_task(void *, 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; | ||||
▲ Show 20 Lines • Show All 488 Lines • ▼ Show 20 Lines | #define ISCAN_REP (ISCAN_MINDWELL | ISCAN_DISCARD) | ||||
struct ieee80211_channel *chan; | struct ieee80211_channel *chan; | ||||
unsigned long maxdwell; | unsigned long maxdwell; | ||||
int scandone = 0; | 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 */ | ||||
goto done; | scan_done(ss, 0); | ||||
return; | |||||
} | } | ||||
if (ss->ss_next == ss->ss_last) { | if (ss->ss_next == ss->ss_last) { | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, | ||||
"%s: no channels to scan\n", __func__); | "%s: no channels to scan\n", __func__); | ||||
scandone = 1; | scan_done(ss, 1); | ||||
goto done; | return; | ||||
} | } | ||||
if (vap->iv_opmode == IEEE80211_M_STA && | if (vap->iv_opmode == IEEE80211_M_STA && | ||||
vap->iv_state == IEEE80211_S_RUN) { | vap->iv_state == IEEE80211_S_RUN) { | ||||
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, | cv_timedwait(&ss_priv->ss_scan_cv, | ||||
IEEE80211_LOCK_OBJ(ic), msecs_to_ticks(1)); | IEEE80211_LOCK_OBJ(ic), msecs_to_ticks(1)); | ||||
if (ss_priv->ss_iflags & ISCAN_ABORT) | if (ss_priv->ss_iflags & ISCAN_ABORT) { | ||||
goto done; | scan_done(ss, 0); | ||||
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); | IEEE80211_LOCK(ic); | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | for (;;) { | ||||
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 */ | /* Wait to be signalled to scan the next channel */ | ||||
cv_wait(&ss_priv->ss_scan_cv, IEEE80211_LOCK_OBJ(ic)); | cv_wait(&ss_priv->ss_scan_cv, IEEE80211_LOCK_OBJ(ic)); | ||||
} | } | ||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: out\n", __func__); | IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: out\n", __func__); | ||||
if (ss_priv->ss_iflags & ISCAN_ABORT) | if (ss_priv->ss_iflags & ISCAN_ABORT) { | ||||
goto done; | scan_done(ss, scandone); | ||||
return; | |||||
} | |||||
IEEE80211_UNLOCK(ic); | IEEE80211_UNLOCK(ic); | ||||
ic->ic_scan_end(ic); /* notify driver */ | ic->ic_scan_end(ic); /* notify driver */ | ||||
IEEE80211_LOCK(ic); | IEEE80211_LOCK(ic); | ||||
/* XXX scan state can change! Re-validate scan state! */ | /* XXX scan state can change! Re-validate scan state! */ | ||||
/* | /* | ||||
* Since a cancellation may have occured during one of the | * Since a cancellation may have occured during one of the | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | #define ISCAN_REP (ISCAN_MINDWELL | ISCAN_DISCARD) | ||||
if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) { | if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) { | ||||
/* XXX printf? */ | /* XXX printf? */ | ||||
if_printf(vap->iv_ifp, | if_printf(vap->iv_ifp, | ||||
"%s: OOPS! scan cancelled during driver call (2)!\n", | "%s: OOPS! scan cancelled during driver call (2)!\n", | ||||
__func__); | __func__); | ||||
scandone = 1; | scandone = 1; | ||||
} | } | ||||
scan_done(ss, scandone); | |||||
} | |||||
static void | |||||
scan_done(struct ieee80211_scan_state *ss, int scandone) | |||||
{ | |||||
struct scan_state *ss_priv = SCAN_PRIVATE(ss); | |||||
struct ieee80211com *ic = ss->ss_ic; | |||||
struct ieee80211vap *vap = ss->ss_vap; | |||||
IEEE80211_LOCK_ASSERT(ic); | |||||
/* | /* | ||||
* Clear the SCAN bit first in case frames are | * Clear the SCAN bit first in case frames are | ||||
* pending on the station power save queue. If | * pending on the station power save queue. If | ||||
* we defer this then the dispatch of the frames | * we defer this then the dispatch of the frames | ||||
* may generate a request to cancel scanning. | * may generate a request to cancel scanning. | ||||
*/ | */ | ||||
done: | |||||
ic->ic_flags &= ~IEEE80211_F_SCAN; | ic->ic_flags &= ~IEEE80211_F_SCAN; | ||||
/* | /* | ||||
* Drop out of power save mode when a scan has | * Drop out of power save mode when a scan has | ||||
* completed. If this scan was prematurely terminated | * completed. If this scan was prematurely terminated | ||||
* because it is a background scan then don't notify | * because it is a background scan then don't notify | ||||
* the ap; we'll either return to scanning after we | * the ap; we'll either return to scanning after we | ||||
* receive the beacon frame or we'll drop out of power | * receive the beacon frame or we'll drop out of power | ||||
* save mode because the beacon indicates we have frames | * save mode because the beacon indicates we have frames | ||||
* waiting for us. | * waiting for us. | ||||
▲ Show 20 Lines • Show All 113 Lines • Show Last 20 Lines |