summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-09-26 00:53:37 +0000
committeradrian <adrian@FreeBSD.org>2015-09-26 00:53:37 +0000
commitf0c602f7159b8780b6ecbba2a6cefdbd729a6cf5 (patch)
tree79cc5ea82f192d5e6161b683bfdb0c511f3b97b9 /sys/net80211
parentede510f112e379b6dfc6618536ae876a80b31fec (diff)
downloadFreeBSD-src-f0c602f7159b8780b6ecbba2a6cefdbd729a6cf5.zip
FreeBSD-src-f0c602f7159b8780b6ecbba2a6cefdbd729a6cf5.tar.gz
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.
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/_ieee80211.h9
-rw-r--r--sys/net80211/ieee80211_freebsd.c37
-rw-r--r--sys/net80211/ieee80211_freebsd.h39
-rw-r--r--sys/net80211/ieee80211_input.c26
-rw-r--r--sys/net80211/ieee80211_proto.h26
5 files changed, 103 insertions, 34 deletions
diff --git a/sys/net80211/_ieee80211.h b/sys/net80211/_ieee80211.h
index 5120d41..4ff395d 100644
--- a/sys/net80211/_ieee80211.h
+++ b/sys/net80211/_ieee80211.h
@@ -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 */
};
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 9a8e941..6fdfb5c 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -491,6 +491,43 @@ ieee80211_process_callback(struct ieee80211_node *ni,
}
/*
+ * 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
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 162cf43..f660c17 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -330,6 +330,8 @@ void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
#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 mbuf *m,
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 */
/*
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index b757ae6..0b95520 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -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 ieee80211com *ic, struct mbuf *m,
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 */
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 165431b..273e759 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -62,32 +62,6 @@ void ieee80211_syncflag(struct ieee80211vap *, int flag);
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);
OpenPOWER on IntegriCloud