From owner-svn-src-head@freebsd.org Sat Sep 26 00:53:39 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A4CBFA09208; Sat, 26 Sep 2015 00:53:39 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 957141A06; Sat, 26 Sep 2015 00:53:39 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8Q0rd6F046532; Sat, 26 Sep 2015 00:53:39 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8Q0rcQD046526; Sat, 26 Sep 2015 00:53:38 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201509260053.t8Q0rcQD046526@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 26 Sep 2015 00:53:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288245 - head/sys/net80211 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 26 Sep 2015 00:53:39 -0000 Author: adrian Date: Sat Sep 26 00:53:37 2015 New Revision: 288245 URL: https://svnweb.freebsd.org/changeset/base/288245 Log: Perform some rather amusing layering violations to add mbuf tags to the net80211 receive path. This allows drivers (notably USB right now, but anything/everything!) to optionally defer bulk RX of 802.11 frames until /outside/ of the driver lock(s), rather than doing: UNLOCK(sc); ieee80211_input*() LOCK(sc); .. which is really stupid. The existing API is maintaned - if ieee80211_input() / ieee80211_input_all() is called then the RSSI/NF values are used. If the MIMO versions are called with a given rx status pointer then it's used. Else, it'll use whatever is in the RX mbuf tag. Modified: head/sys/net80211/_ieee80211.h head/sys/net80211/ieee80211_freebsd.c head/sys/net80211/ieee80211_freebsd.h head/sys/net80211/ieee80211_input.c head/sys/net80211/ieee80211_proto.h Modified: head/sys/net80211/_ieee80211.h ============================================================================== --- head/sys/net80211/_ieee80211.h Sat Sep 26 00:22:09 2015 (r288244) +++ head/sys/net80211/_ieee80211.h Sat Sep 26 00:53:37 2015 (r288245) @@ -390,15 +390,14 @@ 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 + * XXX TODO: IEEE80211_MAX_CHAINS is defined in _freebsd.h, not here; + * figure out how to pull it in! */ struct ieee80211_mimo_info { - int8_t rssi[IEEE80211_MAX_CHAINS]; /* per-antenna rssi */ - int8_t noise[IEEE80211_MAX_CHAINS]; /* per-antenna noise floor */ + int8_t rssi[3]; /* per-antenna rssi */ + int8_t noise[3]; /* per-antenna noise floor */ uint8_t pad[2]; uint32_t evm[3]; /* EVM data */ }; Modified: head/sys/net80211/ieee80211_freebsd.c ============================================================================== --- head/sys/net80211/ieee80211_freebsd.c Sat Sep 26 00:22:09 2015 (r288244) +++ head/sys/net80211/ieee80211_freebsd.c Sat Sep 26 00:53:37 2015 (r288245) @@ -491,6 +491,43 @@ ieee80211_process_callback(struct ieee80 } /* + * Add RX parameters to the given mbuf. + * + * Returns 1 if OK, 0 on error. + */ +int +ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs) +{ + struct m_tag *mtag; + struct ieee80211_rx_params *rx; + + mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, + sizeof(struct ieee80211_rx_stats), M_NOWAIT); + if (mtag == NULL) + return (0); + + rx = (struct ieee80211_rx_params *)(mtag + 1); + memcpy(&rx->params, rxs, sizeof(*rxs)); + m_tag_prepend(m, mtag); + return (1); +} + +int +ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs) +{ + struct m_tag *mtag; + struct ieee80211_rx_params *rx; + + mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, + NULL); + if (mtag == NULL) + return (-1); + rx = (struct ieee80211_rx_params *)(mtag + 1); + memcpy(rxs, &rx->params, sizeof(*rxs)); + return (0); +} + +/* * Transmit a frame to the parent interface. * * TODO: if the transmission fails, make sure the parent node is freed Modified: head/sys/net80211/ieee80211_freebsd.h ============================================================================== --- head/sys/net80211/ieee80211_freebsd.h Sat Sep 26 00:22:09 2015 (r288244) +++ head/sys/net80211/ieee80211_freebsd.h Sat Sep 26 00:53:37 2015 (r288245) @@ -330,6 +330,8 @@ void ieee80211_process_callback(struct i #define NET80211_TAG_XMIT_PARAMS 1 /* See below; this is after the bpf_params definition */ +#define NET80211_TAG_RECV_PARAMS 2 + struct ieee80211com; int ieee80211_parent_xmitpkt(struct ieee80211com *, struct mbuf *); int ieee80211_vap_xmitpkt(struct ieee80211vap *, struct mbuf *); @@ -618,6 +620,43 @@ int ieee80211_add_xmit_params(struct mbu const struct ieee80211_bpf_params *); int ieee80211_get_xmit_params(struct mbuf *m, struct ieee80211_bpf_params *); + +#define IEEE80211_MAX_CHAINS 3 +#define IEEE80211_MAX_EVM_PILOTS 6 + +#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 */ +#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */ +#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */ +#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */ + +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 */ + uint16_t c_freq; + uint8_t c_ieee; +}; + +struct ieee80211_rx_params { + struct ieee80211_rx_stats params; +}; +int ieee80211_add_rx_params(struct mbuf *m, + const struct ieee80211_rx_stats *rxs); +int ieee80211_get_rx_params(struct mbuf *m, + struct ieee80211_rx_stats *rxs); #endif /* _KERNEL */ /* Modified: head/sys/net80211/ieee80211_input.c ============================================================================== --- head/sys/net80211/ieee80211_input.c Sat Sep 26 00:22:09 2015 (r288244) +++ head/sys/net80211/ieee80211_input.c Sat Sep 26 00:53:37 2015 (r288245) @@ -86,10 +86,21 @@ int ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m, struct ieee80211_rx_stats *rx) { + struct ieee80211_rx_stats rxs; + + if (rx) { + memcpy(&rxs, rx, sizeof(*rx)); + } else { + /* try to read from mbuf */ + bzero(&rxs, sizeof(rxs)); + ieee80211_get_rx_params(m, &rxs); + } + /* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */ - ieee80211_process_mimo(ni, rx); + ieee80211_process_mimo(ni, &rxs); + //return ieee80211_input(ni, m, rx->rssi, rx->nf); - return ni->ni_vap->iv_input(ni, m, rx, rx->rssi, rx->nf); + return ni->ni_vap->iv_input(ni, m, &rxs, rxs.rssi, rxs.nf); } int @@ -107,11 +118,20 @@ int ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, struct ieee80211_rx_stats *rx) { + struct ieee80211_rx_stats rxs; struct ieee80211vap *vap; int type = -1; m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */ + if (rx) { + memcpy(&rxs, rx, sizeof(*rx)); + } else { + /* try to read from mbuf */ + bzero(&rxs, sizeof(rxs)); + ieee80211_get_rx_params(m, &rxs); + } + /* XXX locking */ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { struct ieee80211_node *ni; @@ -143,7 +163,7 @@ ieee80211_input_mimo_all(struct ieee8021 m = NULL; } ni = ieee80211_ref_node(vap->iv_bss); - type = ieee80211_input_mimo(ni, mcopy, rx); + type = ieee80211_input_mimo(ni, mcopy, &rxs); ieee80211_free_node(ni); } if (m != NULL) /* no vaps, reclaim mbuf */ Modified: head/sys/net80211/ieee80211_proto.h ============================================================================== --- head/sys/net80211/ieee80211_proto.h Sat Sep 26 00:22:09 2015 (r288244) +++ head/sys/net80211/ieee80211_proto.h Sat Sep 26 00:53:37 2015 (r288245) @@ -62,32 +62,6 @@ 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 */ -#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */ -#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */ -#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */ - -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 */ - uint16_t c_freq; - uint8_t c_ieee; -}; - #define ieee80211_input(ni, m, rssi, nf) \ ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf)) int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int);