summaryrefslogtreecommitdiffstats
path: root/sys/dev/ath/if_athioctl.h
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-06-24 07:01:49 +0000
committeradrian <adrian@FreeBSD.org>2012-06-24 07:01:49 +0000
commita5794ac4d0b0d5211c1507b206f5982a3448b0dd (patch)
tree325748c9b69854f93e26c4b53e25320ef736c7ac /sys/dev/ath/if_athioctl.h
parent7dbe608f0c952ddd5938051793069c9724828e08 (diff)
downloadFreeBSD-src-a5794ac4d0b0d5211c1507b206f5982a3448b0dd.zip
FreeBSD-src-a5794ac4d0b0d5211c1507b206f5982a3448b0dd.tar.gz
Introduce an optional ath(4) radiotap vendor extension.
This includes a few new fields in each RXed frame: * per chain RX RSSI (ctl and ext); * current RX chainmask; * EVM information; * PHY error code; * basic RX status bits (CRC error, PHY error, etc). This is primarily to allow me to do some userland PHY error processing for radar and spectral scan data. However since EVM and per-chain RSSI is provided, others may find it useful for a variety of tasks. The default is to not compile in the radiotap vendor extensions, primarily because tcpdump doesn't seem to handle the particular vendor extension layout I'm using, and I'd rather not break existing code out there that may be (badly) parsing the radiotap data. Instead, add the option 'ATH_ENABLE_RADIOTAP_VENDOR_EXT' to your kernel configuration file to enable these options.
Diffstat (limited to 'sys/dev/ath/if_athioctl.h')
-rw-r--r--sys/dev/ath/if_athioctl.h94
1 files changed, 93 insertions, 1 deletions
diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h
index 0f04b8c..71813ae 100644
--- a/sys/dev/ath/if_athioctl.h
+++ b/sys/dev/ath/if_athioctl.h
@@ -187,7 +187,7 @@ struct ath_diag {
/*
* Radio capture format.
*/
-#define ATH_RX_RADIOTAP_PRESENT ( \
+#define ATH_RX_RADIOTAP_PRESENT_BASE ( \
(1 << IEEE80211_RADIOTAP_TSFT) | \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
@@ -197,8 +197,80 @@ struct ath_diag {
(1 << IEEE80211_RADIOTAP_XCHANNEL) | \
0)
+#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
+#define ATH_RX_RADIOTAP_PRESENT \
+ (ATH_RX_RADIOTAP_PRESENT_BASE | \
+ (1 << IEEE80211_RADIOTAP_VENDOREXT) | \
+ (1 << IEEE80211_RADIOTAP_EXT) | \
+ 0)
+#else
+#define ATH_RX_RADIOTAP_PRESENT ATH_RX_RADIOTAP_PRESENT_BASE
+#endif /* ATH_ENABLE_RADIOTAP_PRESENT */
+
+#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
+/*
+ * This is higher than the vendor bitmap used inside
+ * the Atheros reference codebase.
+ */
+
+/* Bit 8 */
+#define ATH_RADIOTAP_VENDOR_HEADER 8
+
+/*
+ * Using four chains makes all the fields in the
+ * per-chain info header be 4-byte aligned.
+ */
+#define ATH_RADIOTAP_MAX_CHAINS 4
+
+/*
+ * The vendor radiotap header data needs to be:
+ *
+ * + Aligned to a 4 byte address
+ * + .. so all internal fields are 4 bytes aligned;
+ * + .. and no 64 bit fields are allowed.
+ *
+ * So padding is required to ensure this is the case.
+ *
+ * Note that because of the lack of alignment with the
+ * vendor header (6 bytes), the first field must be
+ * two bytes so it can be accessed by alignment-strict
+ * platform (eg MIPS.)
+ */
+struct ath_radiotap_vendor_hdr { /* 30 bytes */
+ uint8_t vh_version; /* 1 */
+ uint8_t vh_rx_chainmask; /* 1 */
+
+ /* At this point it should be 4 byte aligned */
+ uint32_t evm[ATH_RADIOTAP_MAX_CHAINS]; /* 4 * 4 = 16 */
+
+ uint8_t rssi_ctl[ATH_RADIOTAP_MAX_CHAINS]; /* 4 */
+ uint8_t rssi_ext[ATH_RADIOTAP_MAX_CHAINS]; /* 4 */
+
+ uint8_t vh_phyerr_code; /* Phy error code, or 0xff */
+ uint8_t vh_rs_status; /* RX status */
+ uint8_t vh_rssi; /* Raw RSSI */
+ uint8_t vh_pad1[1]; /* Pad to 4 byte boundary */
+} __packed;
+#endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */
+
struct ath_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
+
+#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
+ /* Vendor extension header bitmap */
+ uint32_t wr_ext_bitmap; /* 4 */
+
+ /*
+ * This padding is needed because:
+ * + the radiotap header is 8 bytes;
+ * + the extension bitmap is 4 bytes;
+ * + the tsf is 8 bytes, so it must start on an 8 byte
+ * boundary.
+ */
+ uint32_t wr_pad1;
+#endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */
+
+ /* Normal radiotap fields */
u_int64_t wr_tsf;
u_int8_t wr_flags;
u_int8_t wr_rate;
@@ -210,6 +282,26 @@ struct ath_rx_radiotap_header {
u_int16_t wr_chan_freq;
u_int8_t wr_chan_ieee;
int8_t wr_chan_maxpow;
+
+#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
+ /*
+ * Vendor header section, as required by the
+ * presence of the vendor extension bit and bitmap
+ * entry.
+ *
+ * XXX This must be aligned to a 4 byte address?
+ * XXX or 8 byte address?
+ */
+ struct ieee80211_radiotap_vendor_header wr_vh; /* 6 bytes */
+
+ /*
+ * Because of the lack of alignment enforced by the above
+ * header, this vendor section won't be aligned in any
+ * useful way. So, this will include a two-byte version
+ * value which will force the structure to be 4-byte aligned.
+ */
+ struct ath_radiotap_vendor_hdr wr_v;
+#endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */
} __packed;
#define ATH_TX_RADIOTAP_PRESENT ( \
OpenPOWER on IntegriCloud