svn commit: r220445 - head/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Fri Apr 8 09:20:46 UTC 2011


Author: adrian
Date: Fri Apr  8 09:20:45 2011
New Revision: 220445
URL: http://svn.freebsd.org/changeset/base/220445

Log:
  Add initial support for MIMO statistics to net80211.
  
  This introduces struct ieee80211_rx_stats - which stores the various kinds
  of RX statistics which a MIMO and non-MIMO 802.11 device can export.
  
  It also fleshes out the mimo export to userland (node_getmimoinfo()).
  
  It assumes that MIMO radios (for now) export both ctl and ext channels.
  Non-11n MIMO radios are possible (and I believe Atheros made at least
  one), so if that chipset support is added, extra flags to the
  struct ieee80211_rx_stats can be added to extend this support.
  
  Two new input functions have been added - ieee80211_input_mimo() and
  ieee80211_input_mimo_all() - which MIMO-aware devices can call with
  MIMO specific statistics.
  
  802.11 devices calling the non-MIMO input functions will still function.

Modified:
  head/sys/net80211/_ieee80211.h
  head/sys/net80211/ieee80211_input.c
  head/sys/net80211/ieee80211_node.c
  head/sys/net80211/ieee80211_node.h
  head/sys/net80211/ieee80211_proto.h

Modified: head/sys/net80211/_ieee80211.h
==============================================================================
--- head/sys/net80211/_ieee80211.h	Fri Apr  8 08:49:50 2011	(r220444)
+++ head/sys/net80211/_ieee80211.h	Fri Apr  8 09:20:45 2011	(r220445)
@@ -387,10 +387,16 @@ struct ieee80211_regdomain {
 /*
  * MIMO antenna/radio state.
  */
+
+#define	IEEE80211_MAX_CHAINS		3
+#define	IEEE80211_MAX_EVM_PILOTS	6
+
+/*
+ * XXX This doesn't yet export both ctl/ext chain details
+ */
 struct ieee80211_mimo_info {
-	int8_t		rssi[3];	/* per-antenna rssi */
-	int8_t		noise[3];	/* per-antenna noise floor */
-	uint8_t		pad[2];
+	int8_t		rssi[IEEE80211_MAX_CHAINS];	/* per-antenna rssi */
+	int8_t		noise[IEEE80211_MAX_CHAINS];	/* per-antenna noise floor */
 	uint32_t	evm[3];		/* EVM data */
 };
 #endif /* _NET80211__IEEE80211_H_ */

Modified: head/sys/net80211/ieee80211_input.c
==============================================================================
--- head/sys/net80211/ieee80211_input.c	Fri Apr  8 08:49:50 2011	(r220444)
+++ head/sys/net80211/ieee80211_input.c	Fri Apr  8 09:20:45 2011	(r220445)
@@ -57,9 +57,54 @@ __FBSDID("$FreeBSD$");
 #include <net/ethernet.h>
 #endif
 
+static void
+ieee80211_process_mimo(struct ieee80211_node *ni, struct ieee80211_rx_stats *rx)
+{
+	int i;
+
+	/* Verify the required MIMO bits are set */
+	if ((rx->r_flags & (IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI)) !=
+	    (IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI))
+		return;
+
+	/* XXX This assumes the MIMO radios have both ctl and ext chains */
+	for (i = 0; i < MIN(rx->c_chain, IEEE80211_MAX_CHAINS); i++) {
+		IEEE80211_RSSI_LPF(ni->ni_mimo_rssi_ctl[i], rx->c_rssi_ctl[i]);
+		IEEE80211_RSSI_LPF(ni->ni_mimo_rssi_ext[i], rx->c_rssi_ext[i]);
+	}
+
+	/* XXX This also assumes the MIMO radios have both ctl and ext chains */
+	for(i = 0; i < MIN(rx->c_chain, IEEE80211_MAX_CHAINS); i++) {
+		ni->ni_mimo_noise_ctl[i] = rx->c_nf_ctl[i];
+		ni->ni_mimo_noise_ext[i] = rx->c_nf_ext[i];
+	}
+	ni->ni_mimo_chains = rx->c_chain;
+}
+
+int
+ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m,
+    struct ieee80211_rx_stats *rx)
+{
+	/* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */
+	ieee80211_process_mimo(ni, rx);
+	return ieee80211_input(ni, m, rx->rssi, rx->nf);
+}
+
 int
 ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf)
 {
+	struct ieee80211_rx_stats rx;
+
+	rx.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
+	rx.nf = nf;
+	rx.rssi = rssi;
+	return ieee80211_input_mimo_all(ic, m, &rx);
+}
+
+int
+ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m,
+    struct ieee80211_rx_stats *rx)
+{
 	struct ieee80211vap *vap;
 	int type = -1;
 
@@ -96,7 +141,7 @@ ieee80211_input_all(struct ieee80211com 
 			m = NULL;
 		}
 		ni = ieee80211_ref_node(vap->iv_bss);
-		type = ieee80211_input(ni, mcopy, rssi, nf);
+		type = ieee80211_input_mimo(ni, mcopy, rx);
 		ieee80211_free_node(ni);
 	}
 	if (m != NULL)			/* no vaps, reclaim mbuf */

Modified: head/sys/net80211/ieee80211_node.c
==============================================================================
--- head/sys/net80211/ieee80211_node.c	Fri Apr  8 08:49:50 2011	(r220444)
+++ head/sys/net80211/ieee80211_node.c	Fri Apr  8 09:20:45 2011	(r220445)
@@ -1085,7 +1085,26 @@ static void
 node_getmimoinfo(const struct ieee80211_node *ni,
 	struct ieee80211_mimo_info *info)
 {
-	/* XXX zero data? */
+	int i;
+	uint32_t avgrssi;
+	int32_t rssi;
+
+	bzero(info, sizeof(*info));
+
+	for (i = 0; i < ni->ni_mimo_chains; i++) {
+		avgrssi = ni->ni_mimo_rssi_ctl[i];
+		if (avgrssi == IEEE80211_RSSI_DUMMY_MARKER) {
+			info->rssi[i] = 0;
+		} else {
+			rssi = IEEE80211_RSSI_GET(avgrssi);
+			info->rssi[i] = rssi < 0 ? 0 : rssi > 127 ? 127 : rssi;
+		}
+		info->noise[i] = ni->ni_mimo_noise_ctl[i];
+	}
+
+	/* XXX ext radios? */
+
+	/* XXX EVM? */
 }
 
 struct ieee80211_node *

Modified: head/sys/net80211/ieee80211_node.h
==============================================================================
--- head/sys/net80211/ieee80211_node.h	Fri Apr  8 08:49:50 2011	(r220444)
+++ head/sys/net80211/ieee80211_node.h	Fri Apr  8 09:20:45 2011	(r220445)
@@ -166,6 +166,13 @@ struct ieee80211_node {
 	uint32_t		ni_avgrssi;	/* recv ssi state */
 	int8_t			ni_noise;	/* noise floor */
 
+	/* mimo statistics */
+	uint32_t		ni_mimo_rssi_ctl[IEEE80211_MAX_CHAINS];
+	uint32_t		ni_mimo_rssi_ext[IEEE80211_MAX_CHAINS];
+	uint8_t			ni_mimo_noise_ctl[IEEE80211_MAX_CHAINS];
+	uint8_t			ni_mimo_noise_ext[IEEE80211_MAX_CHAINS];
+	uint8_t			ni_mimo_chains;
+
 	/* header */
 	uint8_t			ni_macaddr[IEEE80211_ADDR_LEN];
 	uint8_t			ni_bssid[IEEE80211_ADDR_LEN];

Modified: head/sys/net80211/ieee80211_proto.h
==============================================================================
--- head/sys/net80211/ieee80211_proto.h	Fri Apr  8 08:49:50 2011	(r220444)
+++ head/sys/net80211/ieee80211_proto.h	Fri Apr  8 09:20:45 2011	(r220445)
@@ -61,9 +61,36 @@ void	ieee80211_syncflag(struct ieee80211
 void	ieee80211_syncflag_ht(struct ieee80211vap *, int flag);
 void	ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
 
+#define	IEEE80211_R_NF		0x0000001	/* global NF value valid */
+#define	IEEE80211_R_RSSI	0x0000002	/* global RSSI value valid */
+#define	IEEE80211_R_C_CHAIN	0x0000004	/* RX chain count valid */
+#define	IEEE80211_R_C_NF	0x0000008	/* per-chain NF value valid */
+#define	IEEE80211_R_C_RSSI	0x0000010	/* per-chain RSSI value valid */
+#define	IEEE80211_R_C_EVM	0x0000020	/* per-chain EVM valid */
+#define	IEEE80211_R_C_HT40	0x0000040	/* RX'ed packet is 40mhz, pilots 4,5 valid */
+
+struct ieee80211_rx_stats {
+	uint32_t r_flags;		/* IEEE80211_R_* flags */
+	uint8_t c_chain;		/* number of RX chains involved */
+	int16_t	c_nf_ctl[IEEE80211_MAX_CHAINS];	/* per-chain NF */
+	int16_t	c_nf_ext[IEEE80211_MAX_CHAINS];	/* per-chain NF */
+	int16_t	c_rssi_ctl[IEEE80211_MAX_CHAINS];	/* per-chain RSSI */
+	int16_t	c_rssi_ext[IEEE80211_MAX_CHAINS];	/* per-chain RSSI */
+	uint8_t nf;			/* global NF */
+	uint8_t rssi;			/* global RSSI */
+	uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
+					/* per-chain, per-pilot EVM values */
+};
+
 #define	ieee80211_input(ni, m, rssi, nf) \
 	((ni)->ni_vap->iv_input(ni, m, rssi, nf))
 int	ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int);
+
+int	ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *,
+	    struct ieee80211_rx_stats *);
+int	ieee80211_input_mimo_all(struct ieee80211com *, struct mbuf *,
+	    struct ieee80211_rx_stats *);
+
 struct ieee80211_bpf_params;
 int	ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
 		struct ieee80211_bpf_params *);


More information about the svn-src-head mailing list