summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-10-28 11:58:52 +0300
committerJohn W. Linville <linville@tuxdriver.com>2009-10-30 23:49:20 +0300
commit6a86b9c78ebd0397eb953493c68ea9e194e7023c (patch)
tree521d05f66acb338a23e3bf6aac077896ae5ca044
parent4d36ec58239eec44d77839ef6c25108efcbbb58c (diff)
downloadlinux-6a86b9c78ebd0397eb953493c68ea9e194e7023c.tar.xz
mac80211: fix radiotap header generation
In commit 601ae7f25aea58f208a7f640f6174aac0652403a Author: Bruno Randolf <br1@einfach.org> Date: Thu May 8 19:22:43 2008 +0200 mac80211: make rx radiotap header more flexible code was added that tried to align the radiotap header position in memory based on the radiotap header length. Quite obviously, that is completely useless. Instead of trying to do that, use unaligned accesses to generate the radiotap header. To properly do that, we also need to mark struct ieee80211_radiotap_header packed, but that is fine since it's already packed (and it should be marked packed anyway since its a wire format). Cc: Bruno Randolf <br1@einfach.org> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/ieee80211_radiotap.h2
-rw-r--r--net/mac80211/rx.c26
2 files changed, 13 insertions, 15 deletions
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 23c3f3d97779..9d3d86aaccbb 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -80,7 +80,7 @@ struct ieee80211_radiotap_header {
* Additional extensions are made
* by setting bit 31.
*/
-};
+} __packed;
/* Name Data type Units
* ---- --------- -----
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5c385e3c1d1f..01df328530ad 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -95,10 +95,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
if (len & 1) /* padding for RX_FLAGS if necessary */
len++;
- /* make sure radiotap starts at a naturally aligned address */
- if (len % 8)
- len = roundup(len, 8);
-
return len;
}
@@ -116,6 +112,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_radiotap_header *rthdr;
unsigned char *pos;
+ u16 rx_flags = 0;
rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
memset(rthdr, 0, rtap_len);
@@ -134,7 +131,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
/* IEEE80211_RADIOTAP_TSFT */
if (status->flag & RX_FLAG_TSFT) {
- *(__le64 *)pos = cpu_to_le64(status->mactime);
+ put_unaligned_le64(status->mactime, pos);
rthdr->it_present |=
cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
pos += 8;
@@ -166,17 +163,17 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos++;
/* IEEE80211_RADIOTAP_CHANNEL */
- *(__le16 *)pos = cpu_to_le16(status->freq);
+ put_unaligned_le16(status->freq, pos);
pos += 2;
if (status->band == IEEE80211_BAND_5GHZ)
- *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
- IEEE80211_CHAN_5GHZ);
+ put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
+ pos);
else if (rate->flags & IEEE80211_RATE_ERP_G)
- *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
- IEEE80211_CHAN_2GHZ);
+ put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
+ pos);
else
- *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_CCK |
- IEEE80211_CHAN_2GHZ);
+ put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
+ pos);
pos += 2;
/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
@@ -205,10 +202,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
/* IEEE80211_RADIOTAP_RX_FLAGS */
/* ensure 2 byte alignment for the 2 byte field as required */
- if ((pos - (unsigned char *)rthdr) & 1)
+ if ((pos - (u8 *)rthdr) & 1)
pos++;
if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
- *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADPLCP);
+ rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
+ put_unaligned_le16(rx_flags, pos);
pos += 2;
}