RadioTap Archive on lore.kernel.org
 help / color / Atom feed
* [RFA] A-MPDU extension
@ 2012-07-05 12:46 Johannes Berg
  0 siblings, 0 replies; only message in thread
From: Johannes Berg @ 2012-07-05 12:46 UTC (permalink / raw)
  To: radiotap-sUITvd46vNxg9hUCZPvPmw

[-- Attachment #1: Type: text/plain, Size: 1899 bytes --]

This is a request for adoption of the long-discussed A-MPDU status
extension. I finally got around to implementing it for testing.

This proposal adds the following field, as also documented on
http://www.radiotap.org/suggested-fields/A-MPDU%20status

Bit Number: 20
Structure: u32 reference number,
           u16 flags,
           u8 delimiter CRC value,
           u8 reserved
Required Alignment: 4 bytes

The presence of this field indicates that the frame was received as part
of an a-MPDU.

The reference number is generated by the capture device and is the same
across each subframe of an A-MPDU. Since the capture device might be
capable of capturing multiple channels or data from multiple
(concurrent) captures could be merged, the reference number is not
guaranteed to be unique across different channels. As a result,
applications should use the channel information together with the
reference number to identify the subframes belonging to the same A-MPDU.

The following flags are defined:

0x0001: driver reports 0-length subframes
0x0002: frame is 0-length subframe (valid only if 0x0001 is set)
0x0004: last subframe is known (should be set for all subframes in an
        A-MPDU)
0x0008: this frame is the last subframe
0x0010: delimiter CRC error
0x0020: delimiter CRC value known: the delimiter CRC value field is
        valid
0xffc0: reserved

Within an A-MPDU, the subframe index can be determined by the
application so it is not included, but depending on the driver reporting
this may miss 0-length subframes.

--- end of description ---


I've attached patches against wireshark to parse and the Linux kernel
(the stack and the iwlwifi driver) to report this field.

Barring any objections, I will repost at the end of the month for and
make the wiki updates to adopt this proposal. At that time, I'll also
file a bug against wireshark to update, with this patch.

johannes

[-- Attachment #2: 0001-wireless-add-radiotap-A-MPDU-status-field.patch --]
[-- Type: text/x-patch, Size: 2641 bytes --]

>From 15827701e153a2ff57a1857b54c86a4d3da1e61d Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Thu, 5 Jul 2012 11:32:16 +0200
Subject: [PATCH 1/4] wireless: add radiotap A-MPDU status field

Define the A-MPDU status field in radiotap, also
update the radiotap parser for it and the MCS field
that was apparently missed last time.

Signed-off-by: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 include/net/ieee80211_radiotap.h |   11 +++++++++++
 net/wireless/radiotap.c          |    2 ++
 2 files changed, 13 insertions(+)

diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 7139254..b273c5b 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -183,6 +183,9 @@ struct ieee80211_radiotap_header {
  *     Contains a bitmap of known fields/flags, the flags, and
  *     the MCS index.
  *
+ * IEEE80211_RADIOTAP_AMPDU_STATUS	u32, u16, u8, u8	unitlesss
+ *
+ *	Contains the AMPDU information for the subframe.
  */
 enum ieee80211_radiotap_type {
 	IEEE80211_RADIOTAP_TSFT = 0,
@@ -205,6 +208,7 @@ enum ieee80211_radiotap_type {
 	IEEE80211_RADIOTAP_DATA_RETRIES = 17,
 
 	IEEE80211_RADIOTAP_MCS = 19,
+	IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
 
 	/* valid in every it_present bitmap, even vendor namespaces */
 	IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
@@ -270,6 +274,13 @@ enum ieee80211_radiotap_type {
 #define IEEE80211_RADIOTAP_MCS_FMT_GF		0x08
 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC		0x10
 
+/* For IEEE80211_RADIOTAP_AMPDU_STATUS */
+#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN		0x0001
+#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN		0x0002
+#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN		0x0004
+#define IEEE80211_RADIOTAP_AMPDU_IS_LAST		0x0008
+#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR		0x0010
+#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN	0x0020
 
 /* helpers */
 static inline int ieee80211_get_radiotap_len(unsigned char *data)
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c4ad795..7d604c0 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -41,6 +41,8 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = {
 	[IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, },
 	[IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, },
 	[IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, },
+	[IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, },
 	/*
 	 * add more here as they are defined in radiotap.h
 	 */
-- 
1.7.10


[-- Attachment #3: 0002-mac80211-optimize-ieee80211_rx_status-struct-layout.patch --]
[-- Type: text/x-patch, Size: 1110 bytes --]

>From 94aabbebe7ea4bb2b297576d2219f28dda914036 Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Thu, 5 Jul 2012 13:14:18 +0200
Subject: [PATCH 2/4] mac80211: optimize ieee80211_rx_status struct layout

We waste a lot of space in this struct because it uses
int values where smaller ones would be sufficient. The
upcoming A-MPDU information needs some space, optimize
the struct now.

Signed-off-by: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 include/net/mac80211.h |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 11d72c0..7ce259b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -709,13 +709,13 @@ enum mac80211_rx_flags {
  */
 struct ieee80211_rx_status {
 	u64 mactime;
-	enum ieee80211_band band;
-	int freq;
-	int signal;
-	int antenna;
-	int rate_idx;
-	int flag;
-	unsigned int rx_flags;
+	u16 flag;
+	u16 freq;
+	u8 rate_idx;
+	u8 rx_flags;
+	u8 band;
+	u8 antenna;
+	s8 signal;
 };
 
 /**
-- 
1.7.10


[-- Attachment #4: 0003-mac80211-support-A-MPDU-status-reporting.patch --]
[-- Type: text/x-patch, Size: 5636 bytes --]

>From 1a0f020c98d5d67085272d83f28890fdddd26494 Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Thu, 5 Jul 2012 11:34:31 +0200
Subject: [PATCH 3/4] mac80211: support A-MPDU status reporting

Support getting A-MPDU status information from the
drivers and reporting it to userspace via radiotap
in the standard fields.

Signed-off-by: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 include/net/mac80211.h |   53 +++++++++++++++++++++++++++++++++++-------------
 net/mac80211/rx.c      |   42 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7ce259b..ae7888a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -670,21 +670,41 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
  * @RX_FLAG_HT_GF: This frame was received in a HT-greenfield transmission, if
  *	the driver fills this value it should add %IEEE80211_RADIOTAP_MCS_HAVE_FMT
  *	to hw.radiotap_mcs_details to advertise that fact
+ * @RX_FLAG_AMPDU_DETAILS: A-MPDU details are known, in particular the reference
+ *	number (@ampdu_reference) must be populated and be a distinct number for
+ *	each A-MPDU
+ * @RX_FLAG_AMPDU_REPORT_ZEROLEN: driver reports 0-length subframes
+ * @RX_FLAG_AMPDU_IS_ZEROLEN: This is a zero-length subframe, for
+ *	monitoring purposes only
+ * @RX_FLAG_AMPDU_LAST_KNOWN: last subframe is known, should be set on all
+ *	subframes of a single A-MPDU
+ * @RX_FLAG_AMPDU_IS_LAST: this subframe is the last subframe of the A-MPDU
+ * @RX_FLAG_AMPDU_DELIM_CRC_ERROR: A delimiter CRC error has been detected
+ *	on this subframe
+ * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
+ *	is stored in the @ampdu_delimiter_crc field)
  */
 enum mac80211_rx_flags {
-	RX_FLAG_MMIC_ERROR	= 1<<0,
-	RX_FLAG_DECRYPTED	= 1<<1,
-	RX_FLAG_MMIC_STRIPPED	= 1<<3,
-	RX_FLAG_IV_STRIPPED	= 1<<4,
-	RX_FLAG_FAILED_FCS_CRC	= 1<<5,
-	RX_FLAG_FAILED_PLCP_CRC = 1<<6,
-	RX_FLAG_MACTIME_MPDU	= 1<<7,
-	RX_FLAG_SHORTPRE	= 1<<8,
-	RX_FLAG_HT		= 1<<9,
-	RX_FLAG_40MHZ		= 1<<10,
-	RX_FLAG_SHORT_GI	= 1<<11,
-	RX_FLAG_NO_SIGNAL_VAL	= 1<<12,
-	RX_FLAG_HT_GF		= 1<<13,
+	RX_FLAG_MMIC_ERROR		= BIT(0),
+	RX_FLAG_DECRYPTED		= BIT(1),
+	RX_FLAG_MMIC_STRIPPED		= BIT(3),
+	RX_FLAG_IV_STRIPPED		= BIT(4),
+	RX_FLAG_FAILED_FCS_CRC		= BIT(5),
+	RX_FLAG_FAILED_PLCP_CRC 	= BIT(6),
+	RX_FLAG_MACTIME_MPDU		= BIT(7),
+	RX_FLAG_SHORTPRE		= BIT(8),
+	RX_FLAG_HT			= BIT(9),
+	RX_FLAG_40MHZ			= BIT(10),
+	RX_FLAG_SHORT_GI		= BIT(11),
+	RX_FLAG_NO_SIGNAL_VAL		= BIT(12),
+	RX_FLAG_HT_GF			= BIT(13),
+	RX_FLAG_AMPDU_DETAILS		= BIT(14),
+	RX_FLAG_AMPDU_REPORT_ZEROLEN	= BIT(15),
+	RX_FLAG_AMPDU_IS_ZEROLEN	= BIT(16),
+	RX_FLAG_AMPDU_LAST_KNOWN	= BIT(17),
+	RX_FLAG_AMPDU_IS_LAST		= BIT(18),
+	RX_FLAG_AMPDU_DELIM_CRC_ERROR	= BIT(19),
+	RX_FLAG_AMPDU_DELIM_CRC_KNOWN	= BIT(20),
 };
 
 /**
@@ -706,16 +726,21 @@ enum mac80211_rx_flags {
  *	HT rates are use (RX_FLAG_HT)
  * @flag: %RX_FLAG_*
  * @rx_flags: internal RX flags for mac80211
+ * @ampdu_reference: A-MPDU reference number, must be a different value for
+ *	each A-MPDU but the same for each subframe within one A-MPDU
+ * @ampdu_delimiter_crc: A-MPDU delimiter CRC
  */
 struct ieee80211_rx_status {
 	u64 mactime;
-	u16 flag;
+	u32 ampdu_reference;
+	u32 flag;
 	u16 freq;
 	u8 rate_idx;
 	u8 rx_flags;
 	u8 band;
 	u8 antenna;
 	s8 signal;
+	u8 ampdu_delimiter_crc;
 };
 
 /**
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d4d82c7..14b5fb4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -60,7 +60,9 @@ static inline int should_drop_frame(struct sk_buff *skb,
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
-	if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
+	if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
+			    RX_FLAG_FAILED_PLCP_CRC |
+			    RX_FLAG_AMPDU_IS_ZEROLEN))
 		return 1;
 	if (unlikely(skb->len < 16 + present_fcs_len))
 		return 1;
@@ -91,6 +93,13 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
 	if (status->flag & RX_FLAG_HT) /* HT info */
 		len += 3;
 
+	if (status->flag & RX_FLAG_AMPDU_DETAILS) {
+		/* padding */
+		while (len & 3)
+			len++;
+		len += 8;
+	}
+
 	return len;
 }
 
@@ -215,6 +224,37 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
 		pos++;
 		*pos++ = status->rate_idx;
 	}
+
+	if (status->flag & RX_FLAG_AMPDU_DETAILS) {
+		u16 flags = 0;
+
+		/* ensure 4 byte alignment */
+		while ((pos - (u8 *)rthdr) & 3)
+			pos++;
+		rthdr->it_present |=
+			cpu_to_le32(1 << IEEE80211_RADIOTAP_AMPDU_STATUS);
+		put_unaligned_le32(status->ampdu_reference, pos);
+		pos += 4;
+		if (status->flag & RX_FLAG_AMPDU_REPORT_ZEROLEN)
+			flags |= IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN;
+		if (status->flag & RX_FLAG_AMPDU_IS_ZEROLEN)
+			flags |= IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN;
+		if (status->flag & RX_FLAG_AMPDU_LAST_KNOWN)
+			flags |= IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN;
+		if (status->flag & RX_FLAG_AMPDU_IS_LAST)
+			flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST;
+		if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR)
+			flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
+		if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
+			flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN;
+		put_unaligned_le16(flags, pos);
+		pos += 2;
+		if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
+			*pos++ = status->ampdu_delimiter_crc;
+		else
+			*pos++ = 0;
+		*pos++ = 0;
+	}
 }
 
 /*
-- 
1.7.10


[-- Attachment #5: 0004-iwlwifi-report-A-MPDU-status.patch --]
[-- Type: text/x-patch, Size: 3394 bytes --]

>From cf0ca5d45dd2008602ecc37495206ae44b748e71 Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Thu, 5 Jul 2012 13:05:08 +0200
Subject: [PATCH 4/4] iwlwifi: report A-MPDU status

Since the firmware will give us an A-MPDU bit and
only a single PHY information packet for all the
subframes in an A-MPDU, we can easily report the
minimal A-MPDU information for radiotap.

Signed-off-by: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 drivers/net/wireless/iwlwifi/dvm/commands.h |    1 +
 drivers/net/wireless/iwlwifi/dvm/dev.h      |    1 +
 drivers/net/wireless/iwlwifi/dvm/rx.c       |   14 +++++++++++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 64811cd..7d84fb54 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -1019,6 +1019,7 @@ struct iwl_wep_cmd {
 #define RX_RES_PHY_FLAGS_MOD_CCK_MSK		cpu_to_le16(1 << 1)
 #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK	cpu_to_le16(1 << 2)
 #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK	cpu_to_le16(1 << 3)
+#define RX_RES_PHY_FLAGS_AGG_MSK		cpu_to_le16(1 << 7)
 #define RX_RES_PHY_FLAGS_ANTENNA_MSK		0xf0
 #define RX_RES_PHY_FLAGS_ANTENNA_POS		4
 
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 54cf085..fee63a7 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -787,6 +787,7 @@ struct iwl_priv {
 	u8 agg_tids_count;
 
 	struct iwl_rx_phy_res last_phy_res;
+	u32 ampdu_ref;
 	bool last_phy_res_valid;
 
 	/*
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index c1f7a18..66415e4 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -668,6 +668,7 @@ static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
 	priv->last_phy_res_valid = true;
+	priv->ampdu_ref++;
 	memcpy(&priv->last_phy_res, pkt->data,
 	       sizeof(struct iwl_rx_phy_res));
 	return 0;
@@ -911,6 +912,8 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
 	u32 ampdu_status;
 	u32 rate_n_flags;
 
+	rx_status.flag = 0;
+
 	/**
 	 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
 	 *	REPLY_RX: physical layer info is in this buffer
@@ -941,6 +944,16 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
 		rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len);
 		ampdu_status = iwlagn_translate_rx_status(priv,
 						le32_to_cpu(rx_pkt_status));
+
+		if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) {
+			/*
+			 * We know which subframes of an A-MPDU belong
+			 * together since we get a single PHY response
+			 * from the firmware for all of them
+			 */
+			rx_status.flag |= RX_FLAG_AMPDU_DETAILS;
+			rx_status.ampdu_reference = priv->ampdu_ref;
+		}
 	}
 
 	if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
@@ -968,7 +981,6 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
 					       rx_status.band);
 	rx_status.rate_idx =
 		iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
-	rx_status.flag = 0;
 
 	/* TSF isn't reliable. In order to allow smooth user experience,
 	 * this W/A doesn't propagate it to the mac80211 */
-- 
1.7.10


[-- Attachment #6: wireshark-ampdu-status.patch --]
[-- Type: text/x-patch, Size: 7261 bytes --]

Index: epan/dissectors/packet-ieee80211-radiotap-defs.h
===================================================================
--- epan/dissectors/packet-ieee80211-radiotap-defs.h	(revision 43572)
+++ epan/dissectors/packet-ieee80211-radiotap-defs.h	(working copy)
@@ -182,6 +182,9 @@
  *     Contains a bitmap of known fields/flags, the flags, and
  *     the MCS index.
  *
+ * IEEE80211_RADIOTAP_AMPDU_STATUS	u32, u16, u8, u8	unitlesss
+ *
+ *	Contains the AMPDU information for the subframe.
  */
 enum ieee80211_radiotap_type {
 	IEEE80211_RADIOTAP_TSFT = 0,
@@ -204,6 +207,7 @@
 	IEEE80211_RADIOTAP_DATA_RETRIES = 17,
 	IEEE80211_RADIOTAP_XCHANNEL = 18, /* Unofficial, used by FreeBSD */
 	IEEE80211_RADIOTAP_MCS = 19,
+	IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
 
 	/* valid in every it_present bitmap, even vendor namespaces */
 	IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
@@ -270,4 +274,13 @@
 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC		0x10
 #define IEEE80211_RADIOTAP_MCS_STBC		0x20
 
+
+/* For IEEE80211_RADIOTAP_AMPDU_STATUS */
+#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN		0x0001
+#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN		0x0002
+#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN		0x0004
+#define IEEE80211_RADIOTAP_AMPDU_IS_LAST		0x0008
+#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR		0x0010
+#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN	0x0020
+
 #endif				/* IEEE80211_RADIOTAP_H */
Index: epan/dissectors/packet-ieee80211-radiotap.c
===================================================================
--- epan/dissectors/packet-ieee80211-radiotap.c	(revision 43572)
+++ epan/dissectors/packet-ieee80211-radiotap.c	(working copy)
@@ -553,6 +553,15 @@
 static int hf_radiotap_mcs_format = -1;
 static int hf_radiotap_mcs_fec = -1;
 static int hf_radiotap_mcs_stbc = -1;
+static int hf_radiotap_ampdu = -1;
+static int hf_radiotap_ampdu_ref = -1;
+static int hf_radiotap_ampdu_flags = -1;
+static int hf_radiotap_ampdu_flags_report_zerolen = -1;
+static int hf_radiotap_ampdu_flags_is_zerolen = -1;
+static int hf_radiotap_ampdu_flags_last_known = -1;
+static int hf_radiotap_ampdu_flags_is_last = -1;
+static int hf_radiotap_ampdu_flags_delim_crc_error = -1;
+static int hf_radiotap_ampdu_delim_crc = -1;
 
 /* "Present" flags */
 static int hf_radiotap_present_tsft = -1;
@@ -601,6 +610,8 @@
 static gint ett_radiotap_vendor = -1;
 static gint ett_radiotap_mcs = -1;
 static gint ett_radiotap_mcs_known = -1;
+static gint ett_radiotap_ampdu = -1;
+static gint ett_radiotap_ampdu_flags = -1;
 
 static dissector_handle_t ieee80211_handle;
 static dissector_handle_t ieee80211_datapad_handle;
@@ -1256,11 +1267,44 @@
 		 {"STBC", "radiotap.mcs.stbc",
 		  FT_BOOLEAN, 8, TFS(&tfs_on_off), IEEE80211_RADIOTAP_MCS_STBC,
 		  "Space Time Block Code", HFILL}},
-
 		{&hf_radiotap_mcs_index,
 		 {"MCS index", "radiotap.mcs.index",
 		  FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
 
+		{&hf_radiotap_ampdu,
+		 {"A-MPDU status", "radiotap.ampdu",
+		  FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
+		{&hf_radiotap_ampdu_ref,
+		 {"A-MPDU reference number", "radiotap.ampdu.reference",
+		  FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+		{&hf_radiotap_ampdu_flags,
+		 {"A-MPDU flags", "radiotap.ampdu.flags",
+		  FT_UINT16, BASE_HEX, NULL, 0x0,
+		  "A-MPDU status flags", HFILL}},
+		{&hf_radiotap_ampdu_flags_report_zerolen,
+		 {"Driver reports 0-length subframes in this A-MPDU", "radiotap.ampdu.flags.report_zerolen",
+		  FT_BOOLEAN, 16, NULL,
+		  IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN, NULL, HFILL}},
+		{&hf_radiotap_ampdu_flags_is_zerolen,
+		 {"This is a 0-length subframe", "radiotap.ampdu.flags.is_zerolen",
+		  FT_BOOLEAN, 16, NULL,
+		  IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN, NULL, HFILL}},
+		{&hf_radiotap_ampdu_flags_last_known,
+		 {"Last subframe of this A-MPDU is known", "radiotap.ampdu.flags.lastknown",
+		  FT_BOOLEAN, 16, NULL,
+		  IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN, NULL, HFILL}},
+		{&hf_radiotap_ampdu_flags_is_last,
+		 {"This is the last subframe of this A-MPDU", "radiotap.ampdu.flags.last",
+		  FT_BOOLEAN, 16, NULL,
+		  IEEE80211_RADIOTAP_AMPDU_IS_LAST, NULL, HFILL}},
+		{&hf_radiotap_ampdu_flags_delim_crc_error,
+		 {"Delimiter CRC error on this subframe", "radiotap.ampdu.flags.delim_crc_error",
+		  FT_BOOLEAN, 16, NULL,
+		  IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR, NULL, HFILL}},
+		{&hf_radiotap_ampdu_delim_crc,
+		 {"A-MPDU subframe delimiter CRC", "radiotap.ampdu.delim_crc",
+		  FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
+
 		{&hf_radiotap_vendor_ns,
 		 {"Vendor namespace", "radiotap.vendor_namespace",
 		  FT_BYTES, BASE_NONE, NULL, 0x0,
@@ -1304,6 +1348,8 @@
 		&ett_radiotap_vendor,
 		&ett_radiotap_mcs,
 		&ett_radiotap_mcs_known,
+		&ett_radiotap_ampdu,
+		&ett_radiotap_ampdu_flags,
 	};
 	module_t *radiotap_module;
 
@@ -2045,7 +2091,47 @@
 			}
 			break;
 		}
+		case IEEE80211_RADIOTAP_AMPDU_STATUS: {
+			proto_item *it;
+			proto_tree *ampdu_tree = NULL, *ampdu_flags_tree;
+			guint32 ref;
+			guint16 flags;
+			guint8 delim_crc;
+
+			ref = tvb_get_letohl(tvb, offset);
+			flags = tvb_get_letohs(tvb, offset + 4);
+			delim_crc = tvb_get_guint8(tvb, offset + 6);
+
+			if (tree) {
+				it = proto_tree_add_item(radiotap_tree, hf_radiotap_ampdu,
+							 tvb, offset, 8, ENC_NA);
+				ampdu_tree = proto_item_add_subtree(it, ett_radiotap_ampdu);
+
+				proto_tree_add_uint(ampdu_tree, hf_radiotap_ampdu_ref,
+						    tvb, offset, 4, ref);
+
+				it = proto_tree_add_uint(ampdu_tree, hf_radiotap_ampdu_flags,
+							 tvb, offset + 4, 2, flags);
+				ampdu_flags_tree = proto_item_add_subtree(it, ett_radiotap_ampdu_flags);
+				proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_report_zerolen,
+						    tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
+				proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_is_zerolen,
+						    tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
+				proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_last_known,
+						    tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
+				proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_is_last,
+						    tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
+				proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_delim_crc_error,
+						    tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
+			}
+			if (flags & IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN) {
+				if (ampdu_tree)
+					proto_tree_add_uint(ampdu_tree, hf_radiotap_ampdu_delim_crc,
+							    tvb, offset + 6, 1, delim_crc);
+			}
+			break;
 		}
+		}
 	}
 
 	if (err != -ENOENT && tree) {
Index: epan/dissectors/packet-ieee80211-radiotap-iter.c
===================================================================
--- epan/dissectors/packet-ieee80211-radiotap-iter.c	(revision 43572)
+++ epan/dissectors/packet-ieee80211-radiotap-iter.c	(working copy)
@@ -50,7 +50,8 @@
 	/* [IEEE80211_RADIOTAP_RTS_RETRIES] = 16 */		{ 1, 1 },
 	/* [IEEE80211_RADIOTAP_DATA_RETRIES] = 17 */		{ 1, 1 },
 	/* [IEEE80211_RADIOTAP_XCHANNEL] = 18 */		{ 0, 0 }, /* Unofficial, used by FreeBSD */
-	/* [IEEE80211_RADIOTAP_MCS] = 19 */			{ 1, 3 }
+	/* [IEEE80211_RADIOTAP_MCS] = 19 */			{ 1, 3 },
+	/* [IEEE80211_RADIOTAP_AMPDU_STATUS] = 20 */		{ 4, 8 }
 	/*
 	 * add more here as they are defined in
 	 * include/net/ieee80211_radiotap.h

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-05 12:46 [RFA] A-MPDU extension Johannes Berg

RadioTap Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/radiotap/0 radiotap/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 radiotap radiotap/ https://lore.kernel.org/radiotap \
		radiotap@radiotap.org
	public-inbox-index radiotap

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.netbsd.radiotap


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git