aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-02 07:18:19 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-05 15:38:35 -0500
commit293702a3fb75832613e2af097bdc3ac8ef775b33 (patch)
treea1047943e21cbbe3634e07fcaab236390b2fd03d
parent1b658f118b11de3c4052ed8cbdd5803cd1fa5670 (diff)
mac80211: use common radiotap code for cooked monitors
There's no need to hardcode a subset of the radiotap header for cooked monitor receive, we can just reuse the normal monitor mode radiotap code. This simplifies the code and extends the information available on cooked monitor interfaces. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/rx.c39
1 files changed, 9 insertions, 30 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c8166adcd600..10bbbd33b314 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -228,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
228{ 228{
229 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); 229 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
230 struct ieee80211_sub_if_data *sdata; 230 struct ieee80211_sub_if_data *sdata;
231 int needed_headroom = 0; 231 int needed_headroom;
232 struct sk_buff *skb, *skb2; 232 struct sk_buff *skb, *skb2;
233 struct net_device *prev_dev = NULL; 233 struct net_device *prev_dev = NULL;
234 int present_fcs_len = 0; 234 int present_fcs_len = 0;
@@ -2544,16 +2544,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2544{ 2544{
2545 struct ieee80211_sub_if_data *sdata; 2545 struct ieee80211_sub_if_data *sdata;
2546 struct ieee80211_local *local = rx->local; 2546 struct ieee80211_local *local = rx->local;
2547 struct ieee80211_rtap_hdr {
2548 struct ieee80211_radiotap_header hdr;
2549 u8 flags;
2550 u8 rate_or_pad;
2551 __le16 chan_freq;
2552 __le16 chan_flags;
2553 } __packed *rthdr;
2554 struct sk_buff *skb = rx->skb, *skb2; 2547 struct sk_buff *skb = rx->skb, *skb2;
2555 struct net_device *prev_dev = NULL; 2548 struct net_device *prev_dev = NULL;
2556 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2549 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2550 int needed_headroom;
2557 2551
2558 /* 2552 /*
2559 * If cooked monitor has been processed already, then 2553 * If cooked monitor has been processed already, then
@@ -2567,30 +2561,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2567 if (!local->cooked_mntrs) 2561 if (!local->cooked_mntrs)
2568 goto out_free_skb; 2562 goto out_free_skb;
2569 2563
2570 if (skb_headroom(skb) < sizeof(*rthdr) && 2564 /* room for the radiotap header based on driver features */
2571 pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) 2565 needed_headroom = ieee80211_rx_radiotap_len(local, status);
2572 goto out_free_skb;
2573
2574 rthdr = (void *)skb_push(skb, sizeof(*rthdr));
2575 memset(rthdr, 0, sizeof(*rthdr));
2576 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
2577 rthdr->hdr.it_present =
2578 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
2579 (1 << IEEE80211_RADIOTAP_CHANNEL));
2580 2566
2581 if (rate) { 2567 if (skb_headroom(skb) < needed_headroom &&
2582 rthdr->rate_or_pad = rate->bitrate / 5; 2568 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
2583 rthdr->hdr.it_present |= 2569 goto out_free_skb;
2584 cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
2585 }
2586 rthdr->chan_freq = cpu_to_le16(status->freq);
2587 2570
2588 if (status->band == IEEE80211_BAND_5GHZ) 2571 /* prepend radiotap information */
2589 rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | 2572 ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
2590 IEEE80211_CHAN_5GHZ);
2591 else
2592 rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN |
2593 IEEE80211_CHAN_2GHZ);
2594 2573
2595 skb_set_mac_header(skb, 0); 2574 skb_set_mac_header(skb, 0);
2596 skb->ip_summed = CHECKSUM_UNNECESSARY; 2575 skb->ip_summed = CHECKSUM_UNNECESSARY;