aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-10-28 04:58:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-30 16:49:20 -0400
commit6a86b9c78ebd0397eb953493c68ea9e194e7023c (patch)
tree521d05f66acb338a23e3bf6aac077896ae5ca044 /net/mac80211/rx.c
parent4d36ec58239eec44d77839ef6c25108efcbbb58c (diff)
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>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c26
1 files changed, 12 insertions, 14 deletions
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,
95 if (len & 1) /* padding for RX_FLAGS if necessary */ 95 if (len & 1) /* padding for RX_FLAGS if necessary */
96 len++; 96 len++;
97 97
98 /* make sure radiotap starts at a naturally aligned address */
99 if (len % 8)
100 len = roundup(len, 8);
101
102 return len; 98 return len;
103} 99}
104 100
@@ -116,6 +112,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
116 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 112 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
117 struct ieee80211_radiotap_header *rthdr; 113 struct ieee80211_radiotap_header *rthdr;
118 unsigned char *pos; 114 unsigned char *pos;
115 u16 rx_flags = 0;
119 116
120 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); 117 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
121 memset(rthdr, 0, rtap_len); 118 memset(rthdr, 0, rtap_len);
@@ -134,7 +131,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
134 131
135 /* IEEE80211_RADIOTAP_TSFT */ 132 /* IEEE80211_RADIOTAP_TSFT */
136 if (status->flag & RX_FLAG_TSFT) { 133 if (status->flag & RX_FLAG_TSFT) {
137 *(__le64 *)pos = cpu_to_le64(status->mactime); 134 put_unaligned_le64(status->mactime, pos);
138 rthdr->it_present |= 135 rthdr->it_present |=
139 cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); 136 cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
140 pos += 8; 137 pos += 8;
@@ -166,17 +163,17 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
166 pos++; 163 pos++;
167 164
168 /* IEEE80211_RADIOTAP_CHANNEL */ 165 /* IEEE80211_RADIOTAP_CHANNEL */
169 *(__le16 *)pos = cpu_to_le16(status->freq); 166 put_unaligned_le16(status->freq, pos);
170 pos += 2; 167 pos += 2;
171 if (status->band == IEEE80211_BAND_5GHZ) 168 if (status->band == IEEE80211_BAND_5GHZ)
172 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | 169 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
173 IEEE80211_CHAN_5GHZ); 170 pos);
174 else if (rate->flags & IEEE80211_RATE_ERP_G) 171 else if (rate->flags & IEEE80211_RATE_ERP_G)
175 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | 172 put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
176 IEEE80211_CHAN_2GHZ); 173 pos);
177 else 174 else
178 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_CCK | 175 put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
179 IEEE80211_CHAN_2GHZ); 176 pos);
180 pos += 2; 177 pos += 2;
181 178
182 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ 179 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
@@ -205,10 +202,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
205 202
206 /* IEEE80211_RADIOTAP_RX_FLAGS */ 203 /* IEEE80211_RADIOTAP_RX_FLAGS */
207 /* ensure 2 byte alignment for the 2 byte field as required */ 204 /* ensure 2 byte alignment for the 2 byte field as required */
208 if ((pos - (unsigned char *)rthdr) & 1) 205 if ((pos - (u8 *)rthdr) & 1)
209 pos++; 206 pos++;
210 if (status->flag & RX_FLAG_FAILED_PLCP_CRC) 207 if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
211 *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADPLCP); 208 rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
209 put_unaligned_le16(rx_flags, pos);
212 pos += 2; 210 pos += 2;
213} 211}
214 212