linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/13] mac80211: Add radiotap support
@ 2007-04-23 18:48 Michael Wu
  2007-04-23 18:48 ` [PATCH 02/13] sync with radiotap header in wireless-2.6 Michael Wu
                   ` (13 more replies)
  0 siblings, 14 replies; 71+ messages in thread
From: Michael Wu @ 2007-04-23 18:48 UTC (permalink / raw)
  To: Jiri Benc; +Cc: linux-wireless, John Linville

From: Michael Wu <flamingice@sourmilk.net>

This patch makes mac80211 monitor interfaces use radiotap headers. It also
provides a bit to let a driver specify a frame has a radiotap header and
another bit to let the driver know if adding a radiotap header would be
helpful.

Thanks to Andy Green <andy@warmcat.com> for testing earlier versions of
this patch.

Signed-off-by: Michael Wu <flamingice@sourmilk.net>
---

 include/net/mac80211.h         |    8 +++-
 net/mac80211/ieee80211.c       |   75 ++++++++++++++++++++++++++++++++++------
 net/mac80211/ieee80211_iface.c |    2 +
 3 files changed, 70 insertions(+), 15 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 1fb4bd9..6392c44 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -216,9 +216,6 @@ struct ieee80211_tx_control {
 	int ifindex;	/* internal */
 };
 
-#define RX_FLAG_MMIC_ERROR       0x1
-#define RX_FLAG_DECRYPTED	0x2
-
 /* Receive status. The low-level driver should provide this information
  * (the subset supported by hardware) to the 802.11 code with each received
  * frame. */
@@ -232,6 +229,9 @@ struct ieee80211_rx_status {
 	int noise;
 	int antenna;
 	int rate;
+#define RX_FLAG_MMIC_ERROR	(1<<0)
+#define RX_FLAG_DECRYPTED	(1<<1)
+#define RX_FLAG_RADIOTAP	(1<<2)
 	int flag;
 };
 
@@ -278,6 +278,8 @@ struct ieee80211_conf {
 #define IEEE80211_CONF_SHORT_SLOT_TIME	(1<<0) /* use IEEE 802.11g Short Slot
 						* Time */
 #define IEEE80211_CONF_SSID_HIDDEN	(1<<1) /* do not broadcast the ssid */
+#define IEEE80211_CONF_RADIOTAP		(1<<2) /* use radiotap if supported
+						  check this bit at RX time */
 	u32 flags;			/* configuration flags defined above */
 
 	u8 power_level;			/* transmit power limit for current
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index ab51a74..51ad624 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -8,6 +8,7 @@
  */
 
 #include <net/mac80211.h>
+#include <net/ieee80211_radiotap.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -291,6 +292,14 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
 }
 EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
 
+static int ieee80211_get_radiotap_len(struct sk_buff *skb)
+{
+	struct ieee80211_radiotap_header *hdr =
+		(struct ieee80211_radiotap_header *) skb->data;
+
+	return le16_to_cpu(hdr->it_len);
+}
+
 #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP
 static void ieee80211_dump_frame(const char *ifname, const char *title,
 				 const struct sk_buff *skb)
@@ -2355,6 +2364,7 @@ static int ieee80211_open(struct net_device *dev)
 		/* run the interface in a "soft monitor" mode */
 		local->monitors++;
 		local->open_count++;
+		local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
 		return 0;
 	}
 	ieee80211_start_soft_monitor(local);
@@ -2403,9 +2413,10 @@ static int ieee80211_open(struct net_device *dev)
 	}
 	local->open_count++;
 
-	if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+	if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
 		local->monitors++;
-	else
+		local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
+	} else
 		ieee80211_if_config(dev);
 
 	if (sdata->type == IEEE80211_IF_TYPE_STA &&
@@ -2430,13 +2441,18 @@ static int ieee80211_stop(struct net_device *dev)
 		/* remove "soft monitor" interface */
 		local->open_count--;
 		local->monitors--;
+		if (!local->monitors)
+			local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
 		return 0;
 	}
 
 	netif_stop_queue(dev);
 
-	if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+	if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
 		local->monitors--;
+		if (!local->monitors)
+			local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
+	}
 
 	local->open_count--;
 	if (local->open_count == 0) {
@@ -2782,26 +2798,53 @@ ieee80211_rx_monitor(struct net_device *dev, struct sk_buff *skb,
 		     struct ieee80211_rx_status *status)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_frame_info *fi;
 	struct ieee80211_sub_if_data *sdata;
-	const size_t hlen = sizeof(struct ieee80211_frame_info)
-				- sizeof(fi->msg_type);
+	struct ieee80211_rate *rate;
+	struct ieee80211_rtap_hdr {
+		struct ieee80211_radiotap_header hdr;
+		u8 flags;
+		u8 rate;
+		__le16 chan_freq;
+		__le16 chan_flags;
+		u8 antsignal;
+	} __attribute__ ((packed)) *rthdr;
 
 	skb->dev = dev;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	if (skb_headroom(skb) < hlen) {
+	if (status->flag & RX_FLAG_RADIOTAP)
+		goto out;
+
+	if (skb_headroom(skb) < sizeof(*rthdr)) {
 		I802_DEBUG_INC(local->rx_expand_skb_head);
-		if (pskb_expand_head(skb, hlen, 0, GFP_ATOMIC)) {
+		if (pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) {
 			dev_kfree_skb(skb);
 			return;
 		}
 	}
 
-	fi = (struct ieee80211_frame_info *) skb_push(skb, hlen);
+	rthdr = (struct ieee80211_rtap_hdr *) skb_push(skb, sizeof(*rthdr));
+	memset(rthdr, 0, sizeof(*rthdr));
+	rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
+	rthdr->hdr.it_present =
+		cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
+			    (1 << IEEE80211_RADIOTAP_RATE) |
+			    (1 << IEEE80211_RADIOTAP_CHANNEL) |
+			    (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL));
+	rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ?
+		       IEEE80211_RADIOTAP_F_FCS : 0;
+	rate = ieee80211_get_rate(local, status->phymode, status->rate);
+	if (rate)
+		rthdr->rate = rate->rate / 5;
+	rthdr->chan_freq = cpu_to_le16(status->freq);
+	rthdr->chan_flags =
+		status->phymode == MODE_IEEE80211A ?
+		cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ) :
+		cpu_to_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ);
+	rthdr->antsignal = status->ssi;
 
-	ieee80211_fill_frame_info(local, fi, status);
+ out:
 	sdata->stats.rx_packets++;
 	sdata->stats.rx_bytes += skb->len;
 
@@ -3397,6 +3440,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx)
 		return TXRX_QUEUED;
 	}
 
+	if (rx->u.rx.status->flag & RX_FLAG_RADIOTAP)
+		skb_pull(rx->skb, ieee80211_get_radiotap_len(rx->skb));
+
 	return TXRX_CONTINUE;
 }
 
@@ -3772,6 +3818,12 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	struct ieee80211_txrx_data rx;
 	u16 type;
 	int multicast;
+	int radiotap_len = 0;
+
+	if (status->flag & RX_FLAG_RADIOTAP) {
+		radiotap_len = ieee80211_get_radiotap_len(skb);
+		skb_pull(skb, radiotap_len);
+	}
 
 	hdr = (struct ieee80211_hdr *) skb->data;
 	memset(&rx, 0, sizeof(rx));
@@ -3808,6 +3860,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 		goto end;
 	skb = rx.skb;
 
+	skb_push(skb, radiotap_len);
 	if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) &&
 	    !local->iff_promiscs && !multicast) {
 		rx.u.rx.ra_match = 1;
@@ -3816,7 +3869,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	} else {
 		struct ieee80211_sub_if_data *prev = NULL;
 		struct sk_buff *skb_new;
-		u8 *bssid = ieee80211_get_bssid(hdr, skb->len);
+		u8 *bssid = ieee80211_get_bssid(hdr, skb->len - radiotap_len);
 
 		list_for_each_entry(sdata, &local->sub_if_list, list) {
 			rx.u.rx.ra_match = 1;
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index b1b20ba..495177b 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -192,7 +192,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
 		break;
 	}
 	case IEEE80211_IF_TYPE_MNTR:
-		dev->type = ARPHRD_IEEE80211_PRISM;
+		dev->type = ARPHRD_IEEE80211_RADIOTAP;
 		break;
 	default:
 		printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",


^ permalink raw reply related	[flat|nested] 71+ messages in thread

end of thread, other threads:[~2007-05-08 17:09 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-23 18:48 [PATCH 01/13] mac80211: Add radiotap support Michael Wu
2007-04-23 18:48 ` [PATCH 02/13] sync with radiotap header in wireless-2.6 Michael Wu
2007-04-23 18:48 ` [PATCH 03/13] mac80211: fix virtual interface related locking Michael Wu
2007-04-23 20:41   ` Jiri Benc
2007-04-23 20:55     ` Michael Wu
2007-04-23 22:20       ` Michael Wu
2007-04-23 20:58   ` Andy Green
2007-04-23 21:21     ` Michael Wu
2007-04-24 18:09       ` Andy Green
2007-04-24 18:24         ` Michael Wu
2007-04-24 18:59           ` John W. Linville
2007-04-25 12:09           ` Johannes Berg
2007-04-23 18:48 ` [PATCH 05/13] mac80211: remove statistics callback for master device Michael Wu
2007-04-23 18:48 ` [PATCH 04/13] mac80211: disable tasklets on close Michael Wu
2007-04-23 20:53   ` Jiri Benc
2007-04-23 18:48 ` [PATCH 07/13] mac80211: fix configuration concurrency issues in ieee80211_sta.c Michael Wu
2007-04-24 16:19   ` Johannes Berg
2007-04-23 18:48 ` [PATCH 06/13] mac80211: avoid flush_scheduled_work Michael Wu
2007-04-23 18:48 ` [PATCH 08/13] mac80211: misc cleanups in ieee80211_sta.c Michael Wu
2007-04-23 18:48 ` [PATCH 09/13] mac80211: remove hw_scan callback Michael Wu
2007-04-24 16:20   ` Johannes Berg
2007-04-26 12:48     ` Michael Wu
2007-04-25  5:03   ` James Ketrenos
2007-04-25 18:16     ` John W. Linville
2007-04-25 20:34       ` Michael Wu
2007-04-26 21:57         ` James Ketrenos
2007-04-27  0:23           ` Michael Wu
2007-04-27  4:14             ` James Ketrenos
2007-04-27  7:44               ` Andy Green
2007-04-27  8:06                 ` James Ketrenos
2007-04-27  8:54                   ` Andy Green
2007-04-27  9:00               ` Jiri Benc
2007-04-27 15:32               ` Michael Wu
2007-04-29 11:55                 ` Guy Cohen
2007-04-27  6:54             ` James Ketrenos
2007-04-27 14:27               ` Michael Wu
2007-05-08 17:08               ` Michael Wu
2007-04-27 14:28             ` Dan Williams
2007-04-27 14:42               ` Jiri Benc
2007-04-27 14:56                 ` Dan Williams
2007-04-27 15:16                   ` Andy Green
2007-04-27 15:22                     ` Johannes Berg
2007-04-27 17:17                       ` James Ketrenos
2007-04-27 17:49                       ` Dan Williams
2007-04-27 18:09                     ` Dan Williams
2007-04-27 18:52                       ` Andy Green
2007-04-27 15:20                   ` Jiri Benc
2007-04-27 15:30                     ` Andy Green
2007-04-27 15:36                       ` Jiri Benc
2007-04-27 15:52                         ` Andy Green
2007-04-27 17:44                         ` James Ketrenos
2007-04-27 17:02                     ` James Ketrenos
2007-04-27 18:10                       ` Jiri Benc
2007-04-27 19:42                         ` Dan Williams
2007-04-27 19:47                           ` Jiri Benc
2007-04-27 19:52                     ` John W. Linville
2007-04-26  3:03       ` James Ketrenos
2007-04-27 20:47   ` James Ketrenos
2007-04-28 13:25     ` Jiri Benc
2007-04-23 18:48 ` [PATCH 11/13] mac80211: fix issues in ieee80211 qdisc Michael Wu
2007-04-23 18:48 ` [PATCH 10/13] mac80211: set bssid to broadcast before scan Michael Wu
2007-04-24 16:24   ` Johannes Berg
2007-04-27 17:40     ` Jiri Benc
2007-04-27 19:49       ` Michael Wu
2007-04-27 21:18         ` Michael Wu
2007-04-27 21:29           ` Michael Wu
2007-04-23 18:48 ` [PATCH 12/13] mac80211: prevent master device from going up without ieee80211 qdisc Michael Wu
2007-04-23 18:48 ` [PATCH 13/13] mac80211: stop all virtual interfaces when master device goes down Michael Wu
2007-04-23 20:58   ` Jiri Benc
2007-04-24 16:16 ` [PATCH 01/13] mac80211: Add radiotap support Johannes Berg
2007-04-28 13:18 ` Jiri Benc

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).