Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Jan 2008 23:18:09 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 133133 for review
Message-ID:  <200801122318.m0CNI9dH046240@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=133133

Change 133133 by sam@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)) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801122318.m0CNI9dH046240>