PERFORCE change 133133 for review
Sam Leffler
sam at FreeBSD.org
Sat Jan 12 15:18:10 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=133133
Change 133133 by sam at sam_ebb on 2008/01/12 23:17:50
maintain per-node rssi state using the LPF scheme that's
employed many other places (and cleanup scan code to use
defs now common)
Affected files ...
.. //depot/projects/vap/sys/net80211/ieee80211_adhoc.c#3 edit
.. //depot/projects/vap/sys/net80211/ieee80211_hostap.c#3 edit
.. //depot/projects/vap/sys/net80211/ieee80211_node.c#18 edit
.. //depot/projects/vap/sys/net80211/ieee80211_node.h#12 edit
.. //depot/projects/vap/sys/net80211/ieee80211_scan_sta.c#15 edit
.. //depot/projects/vap/sys/net80211/ieee80211_sta.c#3 edit
.. //depot/projects/vap/sys/net80211/ieee80211_wds.c#3 edit
Differences ...
==== //depot/projects/vap/sys/net80211/ieee80211_adhoc.c#3 (text+ko) ====
@@ -355,7 +355,7 @@
goto err;
}
}
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
if (HAS_SEQ(type)) {
@@ -714,7 +714,7 @@
sizeof(ni->ni_tstamp));
}
if (ni != NULL) {
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
}
@@ -796,7 +796,7 @@
/* XXX find a better class or define it's own */
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
"%s", "recv probe req");
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_rstamp = rstamp;
rate = ieee80211_setup_rates(ni, rates, xrates,
IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
==== //depot/projects/vap/sys/net80211/ieee80211_hostap.c#3 (text+ko) ====
@@ -507,7 +507,7 @@
goto out;
}
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
if (HAS_SEQ(type)) {
@@ -1053,7 +1053,7 @@
* after the transaction completes.
*/
ni->ni_flags |= IEEE80211_NODE_AREF;
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
if (!ieee80211_alloc_challenge(ni)) {
@@ -1798,7 +1798,7 @@
/* XXX find a better class or define it's own */
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
"%s", "recv probe req");
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_rstamp = rstamp;
rate = ieee80211_setup_rates(ni, rates, xrates,
IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
@@ -2089,7 +2089,7 @@
vap->iv_stats.is_ht_assoc_nohtcap++;
return;
}
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
ni->ni_intval = lintval;
==== //depot/projects/vap/sys/net80211/ieee80211_node.c#18 (text+ko) ====
@@ -445,7 +445,6 @@
printf(" %s%c", ether_sprintf(ni->ni_bssid), fail & 0x20 ? '!' : ' ');
printf(" %3d%c",
ieee80211_chan2ieee(ic, ni->ni_chan), fail & 0x01 ? '!' : ' ');
- printf(" %+4d", ni->ni_rssi);
printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2,
fail & 0x08 ? '!' : ' ');
printf(" %4s%c",
@@ -686,7 +685,7 @@
ni->ni_fhdwell = se->se_fhdwell;
ni->ni_fhindex = se->se_fhindex;
ni->ni_erp = se->se_erp;
- ni->ni_rssi = se->se_rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, se->se_rssi);
ni->ni_noise = se->se_noise;
if (ieee80211_ies_init(&ni->ni_ies, se->se_ies.data, se->se_ies.len)) {
@@ -890,13 +889,19 @@
static int8_t
node_getrssi(const struct ieee80211_node *ni)
{
- return ni->ni_rssi;
+ uint32_t avgrssi = ni->ni_avgrssi;
+ int32_t rssi;
+
+ if (avgrssi == IEEE80211_RSSI_DUMMY_MARKER)
+ return 0;
+ rssi = IEEE80211_RSSI_GET(avgrssi);
+ return rssi < 0 ? 0 : rssi > 127 ? 127 : rssi;
}
static void
node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
{
- *rssi = ni->ni_rssi;
+ *rssi = node_getrssi(ni);
*noise = ni->ni_noise;
}
@@ -932,6 +937,7 @@
ni->ni_authmode = IEEE80211_AUTH_OPEN;
ni->ni_txpower = ic->ic_txpowlimit; /* max power */
ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);
+ ni->ni_avgrssi = IEEE80211_RSSI_DUMMY_MARKER;
ni->ni_inact_reload = nt->nt_inact_init;
ni->ni_inact = ni->ni_inact_reload;
ni->ni_ath_defkeyix = 0x7fff;
@@ -1779,7 +1785,7 @@
ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK,
ni->ni_rxfragstamp);
printf("\trstamp %u rssi %d noise %d intval %u capinfo 0x%x\n",
- ni->ni_rstamp, ni->ni_rssi, ni->ni_noise,
+ ni->ni_rstamp, node_getrssi(ni), ni->ni_noise,
ni->ni_intval, ni->ni_capinfo);
printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n",
ether_sprintf(ni->ni_bssid),
==== //depot/projects/vap/sys/net80211/ieee80211_node.h#12 (text+ko) ====
@@ -140,7 +140,7 @@
/* hardware */
uint32_t ni_rstamp; /* recv timestamp */
- int8_t ni_rssi; /* recv ssi */
+ uint32_t ni_avgrssi; /* recv ssi state */
int8_t ni_noise; /* noise floor */
/* header */
@@ -202,6 +202,38 @@
#define IEEE80211_NODE_STAT_ADD(ni,stat,v) (ni->ni_stats.ns_##stat += v)
#define IEEE80211_NODE_STAT_SET(ni,stat,v) (ni->ni_stats.ns_##stat = v)
+/*
+ * Filtered rssi calculation support. The receive rssi is maintained
+ * as an average over the last 10 frames received using a low pass filter
+ * (all frames for now, possibly need to be more selective). Calculations
+ * are designed such that a good compiler can optimize them. The avg
+ * rssi state should be initialized to IEEE80211_RSSI_DUMMY_MARKER and
+ * each sample incorporated with IEEE80211_RSSI_LPF. Use IEEE80211_RSSI_GET
+ * to extract the current value.
+ *
+ * Note that we assume rssi data are in the range [-127..127] and we
+ * discard values <-20. This is consistent with assumptions throughout
+ * net80211 that signal strength data are in .5 dBm units relative to
+ * the current noise floor (linear, not log).
+ */
+#define IEEE80211_RSSI_LPF_LEN 10
+#define IEEE80211_RSSI_DUMMY_MARKER 127
+/* NB: pow2 to optimize out * and / */
+#define IEEE80211_RSSI_EP_MULTIPLIER (1<<7)
+#define IEEE80211_RSSI_IN(x) ((x) * IEEE80211_RSSI_EP_MULTIPLIER)
+#define _IEEE80211_RSSI_LPF(x, y, len) \
+ (((x) != IEEE80211_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
+#define IEEE80211_RSSI_LPF(x, y) do { \
+ if ((y) >= -20) { \
+ x = _IEEE80211_RSSI_LPF((x), IEEE80211_RSSI_IN((y)), \
+ IEEE80211_RSSI_LPF_LEN); \
+ } \
+} while (0)
+#define IEEE80211_RSSI_EP_RND(x, mul) \
+ ((((x) % (mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define IEEE80211_RSSI_GET(x) \
+ IEEE80211_RSSI_EP_RND(x, IEEE80211_RSSI_EP_MULTIPLIER)
+
static __inline struct ieee80211_node *
ieee80211_ref_node(struct ieee80211_node *ni)
{
==== //depot/projects/vap/sys/net80211/ieee80211_scan_sta.c#15 (text+ko) ====
@@ -65,20 +65,6 @@
#define STA_RSSI_MIN 8 /* min acceptable rssi */
#define STA_RSSI_MAX 40 /* max rssi for comparison */
-#define RSSI_LPF_LEN 10
-#define RSSI_DUMMY_MARKER 0x127
-#define RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */
-#define RSSI_IN(x) ((x) * RSSI_EP_MULTIPLIER)
-#define LPF_RSSI(x, y, len) \
- ((x != RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
-#define RSSI_LPF(x, y) do { \
- if ((y) >= -20) \
- x = LPF_RSSI((x), RSSI_IN((y)), RSSI_LPF_LEN); \
-} while (0)
-#define EP_RND(x, mul) \
- ((((x)%(mul)) >= ((mul)/2)) ? howmany(x, mul) : (x)/(mul))
-#define RSSI_GET(x) EP_RND(x, RSSI_EP_MULTIPLIER)
-
struct sta_entry {
struct ieee80211_scan_entry base;
TAILQ_ENTRY(sta_entry) se_list;
@@ -250,7 +236,7 @@
return 0;
}
se->se_scangen = st->st_scaniter-1;
- se->se_avgrssi = RSSI_DUMMY_MARKER;
+ se->se_avgrssi = IEEE80211_RSSI_DUMMY_MARKER;
IEEE80211_ADDR_COPY(se->base.se_macaddr, macaddr);
TAILQ_INSERT_TAIL(&st->st_entry, se, se_list);
LIST_INSERT_HEAD(&st->st_hash[hash], se, se_hash);
@@ -278,8 +264,8 @@
* NB: use only on-channel data to insure we get a good
* estimate of the signal we'll see when associated.
*/
- RSSI_LPF(se->se_avgrssi, rssi);
- ise->se_rssi = RSSI_GET(se->se_avgrssi);
+ IEEE80211_RSSI_LPF(se->se_avgrssi, rssi);
+ ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi);
ise->se_noise = noise;
}
ise->se_rstamp = rstamp;
==== //depot/projects/vap/sys/net80211/ieee80211_sta.c#3 (text+ko) ====
@@ -552,7 +552,7 @@
vap->iv_stats.is_rx_wrongbss++;
goto out;
}
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
if (HAS_SEQ(type)) {
==== //depot/projects/vap/sys/net80211/ieee80211_wds.c#3 (text+ko) ====
@@ -233,9 +233,12 @@
* Flush pending frames now that were setup.
*/
if (ni != NULL && IEEE80211_NODE_WDSQ_QLEN(ni) != 0) {
+ int8_t rssi, noise;
+
IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni,
"flush wds queue, %u packets queued",
IEEE80211_NODE_WDSQ_QLEN(ni));
+ ic->ic_node_getsignal(ni, &rssi, &noise);
for (;;) {
struct mbuf *m;
@@ -244,9 +247,8 @@
IEEE80211_NODE_WDSQ_UNLOCK(ni);
if (m == NULL)
break;
- /* XXX cheat and re-use last rssi+rstamp */
- ieee80211_input(ni, m,
- ni->ni_rssi, ni->ni_noise, ni->ni_rstamp);
+ /* XXX cheat and re-use last rstamp */
+ ieee80211_input(ni, m, rssi, noise, ni->ni_rstamp);
}
}
}
@@ -568,7 +570,7 @@
vap->iv_stats.is_rx_wrongbss++;
goto out;
}
- ni->ni_rssi = rssi;
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = noise;
ni->ni_rstamp = rstamp;
if (HAS_SEQ(type)) {
More information about the p4-projects
mailing list