From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless <linux-wireless@vger.kernel.org>
Subject: [RFC] mac80211: radiotap vendor data
Date: Sat, 01 May 2010 19:13:51 +0200 [thread overview]
Message-ID: <1272734031.8461.0.camel@jlt3.sipsolutions.net> (raw)
This allows drivers to add radiotap vendor data
to any received frame, which will be simply
passed into userspace and ignored by the kernel.
Can be used by drivers to convey hw-specific
information.
Note: 11n shouldn't be done there, in case somebody
got ideas!!
Note: didn't test this after the paged RX changes
---
drivers/net/wireless/mac80211_hwsim.c | 17 ++++++++++
include/net/mac80211.h | 12 +++++++
net/mac80211/rx.c | 53 ++++++++++++++++++++++++++++++----
3 files changed, 77 insertions(+), 5 deletions(-)
--- wireless-testing.orig/include/net/mac80211.h 2010-05-01 08:46:26.000000000 +0200
+++ wireless-testing/include/net/mac80211.h 2010-05-01 08:47:54.000000000 +0200
@@ -565,6 +565,13 @@ enum mac80211_rx_flags {
* @rate_idx: index of data rate into band's supported rates or MCS index if
* HT rates are use (RX_FLAG_HT)
* @flag: %RX_FLAG_*
+ * @vendor_radiotap_bitmap: radiotap vendor namespace presence bitmap
+ * @vendor_radiotap_len: radiotap vendor namespace length
+ * @vendor_radiotap_align: radiotap vendor namespace alignment. Note
+ * that the actual data must be at the start of the SKB data
+ * already.
+ * @vendor_radiotap_oui: radiotap vendor namespace OUI
+ * @vendor_radiotap_subns: radiotap vendor sub namespace
*/
struct ieee80211_rx_status {
u64 mactime;
@@ -575,6 +582,11 @@ struct ieee80211_rx_status {
int antenna;
int rate_idx;
int flag;
+ u32 vendor_radiotap_bitmap;
+ u16 vendor_radiotap_len;
+ u8 vendor_radiotap_align;
+ u8 vendor_radiotap_oui[3];
+ u8 vendor_radiotap_subns;
};
/**
--- wireless-testing.orig/net/mac80211/rx.c 2010-05-01 08:46:26.000000000 +0200
+++ wireless-testing/net/mac80211/rx.c 2010-05-01 08:47:54.000000000 +0200
@@ -37,6 +37,8 @@
static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
struct sk_buff *skb)
{
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
if (likely(skb->len > FCS_LEN))
__pskb_trim(skb, skb->len - FCS_LEN);
@@ -48,6 +50,9 @@ static struct sk_buff *remove_monitor_in
}
}
+ if (status->vendor_radiotap_len)
+ __pskb_pull(skb, status->vendor_radiotap_len);
+
return skb;
}
@@ -69,8 +74,8 @@ static inline int should_drop_frame(stru
}
static int
-ieee80211_rx_radiotap_len(struct ieee80211_local *local,
- struct ieee80211_rx_status *status)
+ieee80211_rx_radiotap_space(struct ieee80211_local *local,
+ struct ieee80211_rx_status *status)
{
int len;
@@ -87,6 +92,21 @@ ieee80211_rx_radiotap_len(struct ieee802
if (len & 1) /* padding for RX_FLAGS if necessary */
len++;
+ if (status->vendor_radiotap_len) {
+ /* allocate extra bitmap */
+ len += 4;
+
+ if (WARN_ON(status->vendor_radiotap_align == 0))
+ status->vendor_radiotap_align = 1;
+ /* align standard part of vendor namespace */
+ len = ALIGN(len, 2);
+ /* allocate standard part of vendor namespace */
+ len += 6;
+ /* align vendor-defined part */
+ len = ALIGN(len, status->vendor_radiotap_align);
+ /* vendor-defined part is already in skb */
+ }
+
return len;
}
@@ -115,10 +135,18 @@ ieee80211_add_rx_radiotap_header(struct
(1 << IEEE80211_RADIOTAP_CHANNEL) |
(1 << IEEE80211_RADIOTAP_ANTENNA) |
(1 << IEEE80211_RADIOTAP_RX_FLAGS));
- rthdr->it_len = cpu_to_le16(rtap_len);
+ rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
pos = (unsigned char *)(rthdr+1);
+ if (status->vendor_radiotap_len) {
+ rthdr->it_present |=
+ cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) |
+ cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT));
+ put_unaligned_le32(status->vendor_radiotap_bitmap, pos);
+ pos += 4;
+ }
+
/* the order of the following fields is important */
/* IEEE80211_RADIOTAP_TSFT */
@@ -190,11 +218,26 @@ ieee80211_add_rx_radiotap_header(struct
/* IEEE80211_RADIOTAP_RX_FLAGS */
/* ensure 2 byte alignment for the 2 byte field as required */
if ((pos - (u8 *)rthdr) & 1)
- pos++;
+ *pos++ = 0;
if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
put_unaligned_le16(rx_flags, pos);
pos += 2;
+
+ if (status->vendor_radiotap_len) {
+ /* ensure 2 byte alignment for the vendor field as required */
+ if ((pos - (u8 *)rthdr) & 1)
+ *pos++ = 0;
+ *pos++ = status->vendor_radiotap_oui[0];
+ *pos++ = status->vendor_radiotap_oui[1];
+ *pos++ = status->vendor_radiotap_oui[2];
+ *pos++ = status->vendor_radiotap_subns;
+ put_unaligned_le16(status->vendor_radiotap_len, pos);
+ pos += 2;
+ /* align the actual payload as requested */
+ while ((pos - (u8 *)rthdr) & (status->vendor_radiotap_align - 1))
+ *pos++ = 0;
+ }
}
/*
@@ -223,7 +266,7 @@ ieee80211_rx_monitor(struct ieee80211_lo
*/
/* room for the radiotap header based on driver features */
- needed_headroom = ieee80211_rx_radiotap_len(local, status);
+ needed_headroom = ieee80211_rx_radiotap_space(local, status);
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
present_fcs_len = FCS_LEN;
--- wireless-testing.orig/drivers/net/wireless/mac80211_hwsim.c 2010-05-01 08:46:27.000000000 +0200
+++ wireless-testing/drivers/net/wireless/mac80211_hwsim.c 2010-05-01 19:04:57.000000000 +0200
@@ -484,6 +484,7 @@ static bool mac80211_hwsim_tx_frame(stru
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_rx_status rx_status;
+ u8 *vendor_data;
if (data->idle) {
printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n",
@@ -509,6 +510,20 @@ static bool mac80211_hwsim_tx_frame(stru
secpath_reset(skb);
nf_reset(skb);
+ vendor_data = skb_push(skb, 4);
+ rx_status.vendor_radiotap_len = 4;
+ rx_status.vendor_radiotap_align = 4;
+ rx_status.vendor_radiotap_oui[0] = 0xff;
+ rx_status.vendor_radiotap_oui[1] = 0xff;
+ rx_status.vendor_radiotap_oui[2] = 0xff;
+ rx_status.vendor_radiotap_subns = 129;
+ rx_status.vendor_radiotap_bitmap = 0x1;
+
+ *vendor_data++ = 1;
+ *vendor_data++ = 2;
+ *vendor_data++ = 3;
+ *vendor_data++ = 4;
+
/* Copy skb to all enabled radios that are on the current frequency */
spin_lock(&hwsim_radio_lock);
list_for_each_entry(data2, &hwsim_radios, list) {
@@ -535,6 +550,8 @@ static bool mac80211_hwsim_tx_frame(stru
}
spin_unlock(&hwsim_radio_lock);
+ skb_pull(skb, 4);
+
return ack;
}
next reply other threads:[~2010-05-01 17:13 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-01 17:13 Johannes Berg [this message]
2010-05-03 22:16 ` [RFC] mac80211: radiotap vendor data Luis R. Rodriguez
2010-05-04 7:52 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1272734031.8461.0.camel@jlt3.sipsolutions.net \
--to=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).