PERFORCE change 77074 for review
Sam Leffler
sam at FreeBSD.org
Mon May 16 11:44:38 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=77074
Change 77074 by sam at sam_laptop on 2005/05/16 18:44:27
First cut at background scanning; needs testing.
Affected files ...
.. //depot/projects/vap/sys/net80211/ieee80211.c#9 edit
.. //depot/projects/vap/sys/net80211/ieee80211_input.c#10 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#9 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ioctl.h#6 edit
.. //depot/projects/vap/sys/net80211/ieee80211_output.c#11 edit
.. //depot/projects/vap/sys/net80211/ieee80211_proto.c#7 edit
.. //depot/projects/vap/sys/net80211/ieee80211_scan.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_scan.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_scan_ap.c#3 edit
.. //depot/projects/vap/sys/net80211/ieee80211_scan_sta.c#3 edit
.. //depot/projects/vap/sys/net80211/ieee80211_var.h#10 edit
Differences ...
==== //depot/projects/vap/sys/net80211/ieee80211.c#9 (text+ko) ====
@@ -278,6 +278,10 @@
vap->iv_flags |= IEEE80211_F_FF;
if (vap->iv_caps & IEEE80211_C_TURBOP)
vap->iv_flags |= IEEE80211_F_TURBOP;
+ /* NB: bg scanning only makes sense for station mode right now */
+ if (ic->ic_opmode == IEEE80211_M_STA &&
+ (vap->iv_caps & IEEE80211_C_BGSCAN))
+ vap->iv_flags |= IEEE80211_F_BGSCAN;
vap->iv_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */
vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT;
==== //depot/projects/vap/sys/net80211/ieee80211_input.c#10 (text+ko) ====
@@ -531,6 +531,7 @@
ifp->if_ipackets++;
IEEE80211_NODE_STAT(ni, rx_data);
IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len);
+ ic->ic_lastdata = ticks;
#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc))
if (IEEE80211_ATH_CAP(vap, ni, FF) &&
@@ -2318,9 +2319,20 @@
}
if (scan.doth != NULL)
ieee80211_parse_dothparams(vap, scan.doth, wh);
- /* NB: don't need the rest of this */
- if ((ic->ic_flags & IEEE80211_F_SCAN) == 0)
+ if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+ /*
+ * If no data frames have come through
+ * recently and it's been a while since the
+ * last background scan, kick off a new
+ * background scan.
+ */
+ if ((vap->iv_flags & IEEE80211_F_BGSCAN) &&
+ ticks - ic->ic_lastscan >= vap->iv_bgscanintvl &&
+ ticks - ic->ic_lastdata >= vap->iv_bgscanidle)
+ ieee80211_bg_scan(vap);
+ /* NB: don't need the rest of this */
return;
+ }
}
/*
* If scanning, just pass information to the scan module.
==== //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#9 (text+ko) ====
@@ -905,6 +905,15 @@
case IEEE80211_IOC_TURBOP:
ireq->i_val = (vap->iv_flags & IEEE80211_F_TURBOP) != 0;
break;
+ case IEEE80211_IOC_BGSCAN:
+ ireq->i_val = (vap->iv_flags & IEEE80211_F_BGSCAN) != 0;
+ break;
+ case IEEE80211_IOC_BGSCAN_IDLE:
+ ireq->i_val = vap->iv_bgscanidle*1000/hz;/* ms */
+ break;
+ case IEEE80211_IOC_BGSCAN_INTERVAL:
+ ireq->i_val = vap->iv_bgscanintvl/hz; /* seconds */
+ break;
default:
error = EINVAL;
break;
@@ -1708,7 +1717,9 @@
break;
case IEEE80211_IOC_SCAN_REQ:
error = ieee80211_start_scan(vap,
- IEEE80211_SCAN_NOPICK|IEEE80211_SCAN_ACTIVE);
+ IEEE80211_SCAN_ACTIVE |
+ IEEE80211_SCAN_NOPICK |
+ IEEE80211_SCAN_ONCE, IEEE80211_SCAN_FOREVER);
break;
case IEEE80211_IOC_ADDMAC:
case IEEE80211_IOC_DELMAC:
@@ -1768,6 +1779,26 @@
vap->iv_flags &= ~IEEE80211_F_TURBOP;
error = ENETRESET; /* XXX maybe not for station? */
break;
+ case IEEE80211_IOC_BGSCAN:
+ if (ireq->i_val) {
+ if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
+ return EINVAL;
+ vap->iv_flags |= IEEE80211_F_BGSCAN;
+ } else
+ vap->iv_flags &= ~IEEE80211_F_BGSCAN;
+ break;
+ case IEEE80211_IOC_BGSCAN_IDLE:
+ if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN)
+ vap->iv_bgscanidle = ireq->i_val*hz/1000;
+ else
+ error = EINVAL;
+ break;
+ case IEEE80211_IOC_BGSCAN_INTERVAL:
+ if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN)
+ vap->iv_bgscanintvl = ireq->i_val*hz;
+ else
+ error = EINVAL;
+ break;
default:
error = EINVAL;
break;
==== //depot/projects/vap/sys/net80211/ieee80211_ioctl.h#6 (text+ko) ====
@@ -434,6 +434,9 @@
#define IEEE80211_IOC_TURBOP 57 /* ATH turbo' (on, off) */
#define IEEE80211_IOC_WDS 58 /* WDS/4-address handling */
#define IEEE80211_IOC_PUREG 59 /* pure 11g (no 11b stations) */
+#define IEEE80211_IOC_BGSCAN 60 /* bg scanning (on, off) */
+#define IEEE80211_IOC_BGSCAN_IDLE 61 /* bg scan idle threshold */
+#define IEEE80211_IOC_BGSCAN_INTERVAL 62 /* bg scan interval */
/*
* Scan result data returned for IEEE80211_IOC_SCAN_RESULTS.
==== //depot/projects/vap/sys/net80211/ieee80211_output.c#11 (text+ko) ====
@@ -217,6 +217,9 @@
/* NB: parent must be up and running */
if ((parent->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
return;
+ if (vap->iv_state == IEEE80211_S_RUN &&
+ (ic->ic_flags & IEEE80211_F_SCAN)) /* cancel bg scan */
+ ieee80211_cancel_scan(vap);
for (;;) {
/*
* No data frames go out unless we're running.
@@ -290,6 +293,7 @@
} else
ifp->if_opackets++;
}
+ ic->ic_lastdata = ticks;
}
/*
==== //depot/projects/vap/sys/net80211/ieee80211_proto.c#7 (text+ko) ====
@@ -1136,6 +1136,9 @@
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__,
ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
vap->iv_state = nstate; /* state transition */
+ callout_stop(&vap->iv_mgtsend);
+ if (ostate != IEEE80211_S_SCAN)
+ ieee80211_cancel_scan(vap); /* background scan */
ni = vap->iv_bss; /* NB: no reference held */
switch (nstate) {
case IEEE80211_S_INIT:
@@ -1195,10 +1198,6 @@
goto reset;
case IEEE80211_S_AUTH:
reset:
- callout_stop(&vap->iv_mgtsend);
-#if 0
- IF_DRAIN(&ic->ic_mgtq); /* XXX multi-bss */
-#endif
ieee80211_reset_bss(vap);
break;
}
@@ -1220,7 +1219,8 @@
} else {
ieee80211_check_scan(vap,
IEEE80211_SCAN_ACTIVE |
- IEEE80211_SCAN_FLUSH);
+ IEEE80211_SCAN_FLUSH,
+ IEEE80211_SCAN_FOREVER);
}
break;
case IEEE80211_S_SCAN:
@@ -1238,7 +1238,8 @@
case IEEE80211_S_ASSOC:
/* timeout restart scan */
ieee80211_scan_assocfail(ic, vap->iv_bss->ni_macaddr);
- ieee80211_check_scan(vap, IEEE80211_SCAN_ACTIVE | arg);
+ ieee80211_check_scan(vap, IEEE80211_SCAN_ACTIVE | arg,
+ IEEE80211_SCAN_FOREVER);
break;
}
break;
@@ -1309,7 +1310,6 @@
if (vap->iv_flags & IEEE80211_F_WPA) {
/* XXX validate prerequisites */
}
- callout_stop(&vap->iv_mgtsend);
ifp->if_flags &= ~IFF_OACTIVE;
switch (ostate) {
case IEEE80211_S_INIT:
@@ -1358,7 +1358,8 @@
* AP. We delay until here to allow configuration to
* happen out of order.
*/
- if (vap->iv_opmode == IEEE80211_M_HOSTAP && /* XXX IBSS/AHDEMO */
+ if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
+ /* XXX IBSS/AHDEMO */
vap->iv_auth->ia_attach != NULL) {
/* XXX check failure */
vap->iv_auth->ia_attach(vap);
==== //depot/projects/vap/sys/net80211/ieee80211_scan.c#2 (text+ko) ====
@@ -78,6 +78,8 @@
void
ieee80211_scan_vattach(struct ieee80211vap *vap)
{
+ vap->iv_bgscanidle = (IEEE80211_BGSCAN_IDLE_DEFAULT*1000)/hz;
+ vap->iv_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT*hz;
}
void
@@ -204,7 +206,7 @@
* Kick off the scanning thread.
*/
static void
-start_timer(struct ieee80211_scan_state *ss)
+start_timer(struct ieee80211_scan_state *ss, u_int duration)
{
int delay;
@@ -215,9 +217,12 @@
* XXX 1ms is a lot, better to trigger scan
* on tx complete.
*/
- delay = hz/100;
+ delay = hz/1000;
+ if (delay < 1)
+ delay = 1;
} else
delay = 1;
+ ss->ss_scanend = ticks + delay + duration;
callout_reset(&ss->ss_scan_timer, delay, ieee80211_next_scan, ss);
}
@@ -225,7 +230,7 @@
* Start a scan unless one is already going.
*/
int
-ieee80211_start_scan(struct ieee80211vap *vap, int flags)
+ieee80211_start_scan(struct ieee80211vap *vap, int flags, u_int duration)
{
struct ieee80211com *ic = vap->iv_ic;
const struct ieee80211_scanner *scan;
@@ -243,12 +248,14 @@
IEEE80211_LOCK(ic);
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
- "%s: %s scan, desired mode %s, %s%s\n"
+ "%s: %s scan, duration %lu, desired mode %s, %s%s%s\n"
, __func__
, flags & IEEE80211_SCAN_ACTIVE ? "active" : "passive"
+ , duration
, ieee80211_phymode_name[vap->iv_des_mode]
, flags & IEEE80211_SCAN_FLUSH ? "flush" : "append"
, flags & IEEE80211_SCAN_NOPICK ? ", nopick" : ""
+ , flags & IEEE80211_SCAN_ONCE ? ", once" : ""
);
ss->ss_vap = vap;
@@ -277,7 +284,7 @@
/* NB: flush frames rx'd before 1st channel change */
ss->ss_flags |= IEEE80211_SCAN_DISCARD;
ss->ss_ops->scan_start(ss, vap);
- start_timer(ss);
+ start_timer(ss, duration);
ic->ic_flags |= IEEE80211_F_SCAN;
}
} else {
@@ -296,7 +303,7 @@
* fails then kick off a new scan.
*/
int
-ieee80211_check_scan(struct ieee80211vap *vap, int flags)
+ieee80211_check_scan(struct ieee80211vap *vap, int flags, u_int duration)
{
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_scan_state *ss = &ic->ic_scan;
@@ -334,37 +341,76 @@
/* no ap, clear the flag before starting a scan */
ic->ic_flags &= ~IEEE80211_F_SCAN;
}
- return ieee80211_start_scan(vap, flags);
+ return ieee80211_start_scan(vap, flags, duration);
}
/*
- * Restart a previous scan. The existing scan state is left
- * untouched, we just restart the thread and it will pickup
- * where we left off.
+ * Restart a previous scan. If the previous scan completed
+ * then we start again using the existing channel list.
*/
int
-ieee80211_restart_scan(struct ieee80211vap *vap)
+ieee80211_bg_scan(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_scan_state *ss = &ic->ic_scan;
IEEE80211_LOCK(ic);
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+ u_int duration, fudge;
+
+ /*
+ * Calculate the schedule for going off-channel. We
+ * need to return in time to receive the next beacon
+ * so we use the beacon interval minus the time required
+ * to be ready to rx the beacon. This is device-dependent
+ * but for now we use 1ms. Note that this only works
+ * because we are called on receipt of a beacon frame;
+ * otherwise we'd need to check TSF and calculate nexttbtt
+ * or (more likely) arrange to start at the next beacon.
+ */
+ duration = IEEE80211_TU_TO_TICKS(vap->iv_bss->ni_intval);
+ fudge = hz/1000;
+ if (fudge == 0)
+ fudge = 1;
+ if (duration > fudge)
+ duration -= fudge;
+ /* XXX do we sanity check beacon interval anywhere? */
+
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
- "%s: %s scan\n", __func__,
- ic->ic_flags & IEEE80211_F_SCAN ? "active" : "passive");
+ "%s: %s scan, duration %lu\n", __func__,
+ ic->ic_flags & IEEE80211_F_SCAN ? "active" : "passive",
+ duration);
if (ss->ss_ops != NULL) {
- ss->ss_vap = vap; /* XXX temporary */
- if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
- vap->iv_stats.is_scan_active++;
- else
- vap->iv_stats.is_scan_passive++;
-
+ ss->ss_vap = vap;
+ /*
+ * A background scan does not select a new sta; it
+ * just refreshes the scan cache. Also, indicate
+ * the scan logic should follow the beacon schedule:
+ * we go off-channel and scan for as much of the
+ * beacon interval as we can, return to the bss channel
+ * to receive the beacon, then go off-channel again.
+ * All during this time we notify the ap we're in power
+ * save mode. When the scan is complete we leave power
+ * save mode. If any beacon indicates there are frames
+ * pending for us then we drop out of power save mode
+ * (and background scan) automatically by way of the
+ * usual sta power save logic.
+ */
+ ss->ss_flags |= IEEE80211_SCAN_NOPICK
+ | IEEE80211_SCAN_BGSCAN;
+ /* if previous scan completed, restart */
+ if (ss->ss_next >= ss->ss_last) {
+ ss->ss_next = 0;
+ if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
+ vap->iv_stats.is_scan_active++;
+ else
+ vap->iv_stats.is_scan_passive++;
+ }
/* NB: flush frames rx'd before 1st channel change */
ss->ss_flags |= IEEE80211_SCAN_DISCARD;
ss->ss_ops->scan_restart(ss, vap);
- start_timer(ss);
+ start_timer(ss, duration);
ic->ic_flags |= IEEE80211_F_SCAN;
} else {
/* XXX msg+stat */
@@ -381,7 +427,7 @@
}
/*
- * Cancel any active scan.
+ * Cancel any scan currently going on.
*/
void
ieee80211_cancel_scan(struct ieee80211vap *vap)
@@ -396,6 +442,7 @@
IEEE80211_LOCK(ic);
if (ic->ic_flags & IEEE80211_F_SCAN) {
callout_drain(&ss->ss_scan_timer);
+ /* XXX maybe this should be handled in the timer routine? */
ic->ic_flags &= ~IEEE80211_F_SCAN;
ss->ss_ops->scan_cancel(ss, vap);
/* return to previous channel if needed */
@@ -405,7 +452,9 @@
/* XXX ieee80211_end_scan or otherwise notify? */
if (ss->ss_flags & IEEE80211_SCAN_PWRSAV)
ieee80211_sta_pwrsave(vap, 0);
- ss->ss_flags &= ~IEEE80211_SCAN_MINDWELL;
+ /* clear ephemeral state bits */
+ ss->ss_flags &= ~(IEEE80211_SCAN_MINDWELL |
+ IEEE80211_SCAN_BGSCAN | IEEE80211_SCAN_ONCE);
}
IEEE80211_UNLOCK(ic);
}
@@ -421,7 +470,7 @@
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_channel *chan;
unsigned long maxdwell;
- int scanning, i;
+ int scanning, scandone, i;
IEEE80211_LOCK(ic);
scanning = (ic->ic_flags & IEEE80211_F_SCAN) != 0;
@@ -431,8 +480,8 @@
/* XXX if taking first candidate check for a valid result */
again:
- if (ss->ss_next < ss->ss_last &&
- time_before(ticks + ss->ss_mindwell, ss->ss_scanend)) {
+ scandone = (ss->ss_next >= ss->ss_last);
+ if (!scandone && time_before(ticks + ss->ss_mindwell, ss->ss_scanend)) {
chan = ss->ss_chans[ss->ss_next++];
/*
@@ -444,7 +493,7 @@
maxdwell = ss->ss_maxdwell;
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
- "%s: chan %3d%c -> %3d%c [%s, dwell min %ld max %ld]\n",
+ "%s: chan %3d%c -> %3d%c [%s, dwell min %lu max %lu]\n",
__func__,
ieee80211_chan2ieee(ic, ic->ic_curchan),
channel_type(ic->ic_curchan),
@@ -506,13 +555,16 @@
* ss_scan_end may decide differently.
*/
ic->ic_scan_end(ic); /* notify driver */
+ if (scandone) /* record scan complete time */
+ ic->ic_lastscan = ticks;
/* clear mindwell lock and initial channel change flush */
ss->ss_flags &=
~(IEEE80211_SCAN_MINDWELL | IEEE80211_SCAN_DISCARD);
if (!ss->ss_ops->scan_end(ss, vap) &&
+ (ss->ss_flags & IEEE80211_SCAN_ONCE) == 0 &&
time_before(ticks + ss->ss_mindwell, ss->ss_scanend)) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
- "%s: scan done, restart "
+ "%s: done, restart "
"[ticks %lu, dwell min %lu scanend %lu]\n",
__func__,
ticks, ss->ss_mindwell, ss->ss_scanend);
@@ -525,18 +577,34 @@
ic->ic_scan_start(ic); /* notify driver */
goto again;
} else {
+ /* past here, scandone is ``true'' if not in bg mode */
+ if ((ss->ss_flags & IEEE80211_SCAN_BGSCAN) == 0)
+ scandone = 1;
+ ss->ss_flags &= ~IEEE80211_SCAN_ONCE;
+
IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
- "%s: scan done, completed "
- "[ticks %lu, dwell min %lu scanend %lu]\n",
- __func__,
+ "%s: %s, [ticks %lu, dwell min %lu scanend %lu]\n",
+ __func__, scandone ? "done" : "stopped",
ticks, ss->ss_mindwell, ss->ss_scanend);
- if (ss->ss_flags & IEEE80211_SCAN_PWRSAV) {
- if (ss->ss_savchan != ic->ic_curchan)
- change_channel(ic, ss->ss_savchan);
+
+ /* return to the original channel */
+ if (ss->ss_savchan != ic->ic_curchan)
+ change_channel(ic, ss->ss_savchan);
+ /*
+ * Drop out of power save mode when a scan has
+ * completed. If this scan was prematurely terminated
+ * because it is a background scan then don't notify
+ * the ap; we'll either return to scanning after we
+ * receive the beacon frame or we'll drop out of power
+ * save mode because the beacon indicates we have frames
+ * waiting for us.
+ */
+ if (scandone && (ss->ss_flags & IEEE80211_SCAN_PWRSAV))
ieee80211_sta_pwrsave(vap, 0);
- }
ic->ic_flags &= ~IEEE80211_F_SCAN;
- ieee80211_notify_scan_done(vap);
+ /* NB: suppress notification during bg scan */
+ if (scandone)
+ ieee80211_notify_scan_done(vap);
}
}
}
==== //depot/projects/vap/sys/net80211/ieee80211_scan.h#2 (text+ko) ====
@@ -43,6 +43,9 @@
u_int16_t ss_flags;
#define IEEE80211_SCAN_NOPICK 0x0001 /* scan only, no selection */
#define IEEE80211_SCAN_ACTIVE 0x0002 /* active scan (probe req) */
+#define IEEE80211_SCAN_PICK1ST 0x0004 /* ``hey sailor'' mode */
+#define IEEE80211_SCAN_BGSCAN 0x0008 /* bg scan, exit ps at end */
+#define IEEE80211_SCAN_ONCE 0x0010 /* do one complete pass */
#define IEEE80211_SCAN_PWRSAV 0x1000 /* exit power save mode */
#define IEEE80211_SCAN_MINDWELL 0x2000 /* min dwell time reached */
#define IEEE80211_SCAN_DISCARD 0x4000 /* discard rx'd frames */
@@ -81,9 +84,10 @@
void ieee80211_scan_dump_channels(const struct ieee80211_scan_state *);
-int ieee80211_start_scan(struct ieee80211vap *, int flags);
-int ieee80211_check_scan(struct ieee80211vap *, int flags);
-int ieee80211_restart_scan(struct ieee80211vap *);
+#define IEEE80211_SCAN_FOREVER 0x7fffffff
+int ieee80211_start_scan(struct ieee80211vap *, int flags, u_int duration);
+int ieee80211_bg_scan(struct ieee80211vap *);
+int ieee80211_check_scan(struct ieee80211vap *, int flags, u_int duration);
void ieee80211_cancel_scan(struct ieee80211vap *);
int ieee80211_match_bss(struct ieee80211vap *, struct ieee80211_node *);
==== //depot/projects/vap/sys/net80211/ieee80211_scan_ap.c#3 (text+ko) ====
@@ -294,15 +294,13 @@
/* XXX tunables */
ss->ss_mindwell = 200*hz/1000; /* 200ms */
ss->ss_maxdwell = 300*hz/1000; /* 300ms */
- /* arrange to scan only once */
- ss->ss_scanend = ticks + ss->ss_last * ss->ss_maxdwell;
#ifdef IEEE80211_DEBUG
if (ieee80211_msg_scan(vap)) {
if_printf(&vap->iv_if, "scan set ");
ieee80211_scan_dump_channels(ss);
- printf(" dwell min %ld max %ld scanend %ld\n",
- ss->ss_mindwell, ss->ss_maxdwell, ss->ss_scanend);
+ printf(" dwell min %ld max %ld\n",
+ ss->ss_mindwell, ss->ss_maxdwell);
}
#endif /* IEEE80211_DEBUG */
==== //depot/projects/vap/sys/net80211/ieee80211_scan_sta.c#3 (text+ko) ====
@@ -88,6 +88,7 @@
};
static void sta_flush_table(struct sta_table *);
+static int match_bss(struct ieee80211vap *, struct ieee80211_scan_entry *);
/*
* Attach prior to any scanning work.
@@ -178,7 +179,8 @@
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
struct sta_table *st = ss->ss_priv;
const u_int8_t *macaddr = wh->i_addr2;
- struct ieee80211com *ic = ss->ss_vap->iv_ic;
+ struct ieee80211vap *vap = ss->ss_vap;
+ struct ieee80211com *ic = vap->iv_ic;
struct sta_entry *se;
struct ieee80211_scan_entry *ise;
int hash;
@@ -238,7 +240,17 @@
se->se_lastupdate = ticks; /* update time */
mtx_unlock(&st->st_lock);
-
+#if 0
+ /*
+ * If scanning for the first acceptable candidate,
+ * check capabilities and verify the rssi is acceptable.
+ */
+ if ((ss->ss_flags & IEEE80211_SCAN_PICK1ST) &&
+ match_bss(vap, ise) == 0 &&
+ RSSI_GET(se->se_avgrssi) >= RSSI_MINACCEPTABLE) {
+ /* arrange to terminate scan and associate */
+ }
+#endif
return 1;
#undef ISPROBE
}
@@ -253,9 +265,11 @@
if (vap->iv_opmode == IEEE80211_M_STA &&
vap->iv_state == IEEE80211_S_RUN) {
- /* initiate power save before going off-channel */
- ieee80211_sta_pwrsave(vap, 1);
- ss->ss_flags |= IEEE80211_SCAN_PWRSAV;
+ if ((ss->ss_flags & IEEE80211_SCAN_PWRSAV) == 0) {
+ /* initiate power save before going off-channel */
+ ieee80211_sta_pwrsave(vap, 1);
+ ss->ss_flags |= IEEE80211_SCAN_PWRSAV;
+ }
} else
ss->ss_flags &= ~IEEE80211_SCAN_PWRSAV;
@@ -447,14 +461,13 @@
/* XXX tunables */
ss->ss_mindwell = 20*hz/1000; /* 20ms */
ss->ss_maxdwell = 200*hz/1000; /* 200ms */
- ss->ss_scanend = ticks+0x7fffffff; /* scan ``forever'' */
#ifdef IEEE80211_DEBUG
if (ieee80211_msg_scan(vap)) {
if_printf(&vap->iv_if, "scan set ");
ieee80211_scan_dump_channels(ss);
- printf(" dwell min %ld max %ld scanend %ld\n",
- ss->ss_mindwell, ss->ss_maxdwell, ss->ss_scanend);
+ printf(" dwell min %ld max %ld\n",
+ ss->ss_mindwell, ss->ss_maxdwell);
}
#endif /* IEEE80211_DEBUG */
==== //depot/projects/vap/sys/net80211/ieee80211_var.h#10 (text+ko) ====
@@ -70,11 +70,18 @@
#define IEEE80211_BINTVAL_MIN 25 /* min beacon interval (TU's) */
#define IEEE80211_BINTVAL_DEFAULT 100 /* default beacon interval (TU's) */
+#define IEEE80211_BGSCAN_INTVAL_MIN 30 /* min bg scan intvl (secs) */
+#define IEEE80211_BGSCAN_INTVAL_DEFAULT (5*60) /* default bg scan intvl */
+
+#define IEEE80211_BGSCAN_IDLE_MIN 500 /* min idle time (ms) */
+#define IEEE80211_BGSCAN_IDLE_DEFAULT (10*1000) /* default idle time (ms) */
+
#define IEEE80211_PS_SLEEP 0x1 /* STA is in power saving mode */
#define IEEE80211_PS_MAX_QUEUE 50 /* maximum saved packets */
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
#define IEEE80211_TU_TO_MS(x) (((x) * 1024) / 1000)
+#define IEEE80211_TU_TO_TICKS(x) ((IEEE80211_TU_TO_MS(x) * hz) / 1000)
#define IEEE80211_PWRCONSTRAINT_VAL(ic) \
(((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \
@@ -151,6 +158,8 @@
/* scan-related state */
struct ieee80211_scan_state ic_scan; /* scan state */
enum ieee80211_roamingmode ic_roaming; /* roaming mode */
+ int ic_lastdata; /* time of last data frame */
+ int ic_lastscan; /* time last scan completed */
/* NB: this is the union of all vap stations/neighbors */
struct ieee80211_node_table ic_sta; /* stations/neighbors */
@@ -248,6 +257,8 @@
u_int16_t iv_des_mode; /* desired mode */
int iv_nicknamelen; /* XXX junk */
u_int8_t iv_nickname[IEEE80211_NWID_LEN];
+ u_int iv_bgscanidle; /* bg scan idle threshold */
+ u_int iv_bgscanintvl; /* bg scan min interval */
u_int32_t *iv_aid_bitmap; /* association id map */
u_int16_t iv_max_aid;
@@ -305,6 +316,7 @@
#define IEEE80211_F_PMGTON 0x00000800 /* CONF: Power mgmt enable */
#define IEEE80211_F_DESBSSID 0x00001000 /* CONF: des_bssid is set */
#define IEEE80211_F_WME 0x00002000 /* CONF: enable WME use */
+#define IEEE80211_F_BGSCAN 0x00004000 /* CONF: bg scan enabled */
#define IEEE80211_F_SWRETRY 0x00008000 /* CONF: sw tx retry enabled */
#define IEEE80211_F_TXPOW_FIXED 0x00010000 /* TX Power: fixed rate */
#define IEEE80211_F_IBSSON 0x00020000 /* CONF: IBSS creation enable */
@@ -348,6 +360,7 @@
#define IEEE80211_C_BURST 0x02000000 /* CAPABILITY: frame bursting */
#define IEEE80211_C_WME 0x04000000 /* CAPABILITY: WME avail */
#define IEEE80211_C_WDS 0x08000000 /* CAPABILITY: 4-addr support */
+#define IEEE80211_C_BGSCAN 0x10000000 /* CAPABILITY: bg scanning */
/* XXX protection/barker? */
#define IEEE80211_C_CRYPTO 0x0000002f /* CAPABILITY: crypto alg's */
@@ -355,7 +368,8 @@
(IEEE80211_C_CRYPTO | IEEE80211_C_FF | IEEE80211_C_TURBOP | \
IEEE80211_C_PMGT | IEEE80211_C_SWRETRY | IEEE80211_C_TXPMGT | \
IEEE80211_C_SHSLOT | IEEE80211_C_SHPREAMBLE | IEEE80211_C_TKIPMIC | \
- IEEE80211_C_WPA | IEEE80211_C_BURST | IEEE80211_C_WME)
+ IEEE80211_C_WPA | IEEE80211_C_BURST | IEEE80211_C_WME | \
+ IEEE80211_C_BGSCAN)
/* check if a capability was negotiated for use */
#define IEEE80211_ATH_CAP(vap, ni, bit) \
More information about the p4-projects
mailing list