aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/common.c
diff options
context:
space:
mode:
authorBenoit PAPILLAULT <benoit.papillault@free.fr>2009-11-19 16:19:26 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-23 17:05:28 -0500
commit8c35024aa65c079f800df7778869a8dbda074182 (patch)
tree397be73ae2be02001201601024a9502817078c30 /drivers/net/wireless/ath/ath9k/common.c
parentac2752c145c6dd25b8ed26bfede1c9177c91a7ef (diff)
ath9k: This patch fix RX unpadding for any received frame.
It has been tested with a 802.11 frame generator and by checking the FCS field of each received frame with the value reported by the Atheros hardware. This patch is useful if you are trying to analyze non standard 802.11 frame going over the air. Signed-off-by: Benoit PAPILLAULT <benoit.papillault@free.fr> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/common.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 2f1e1612e2ad..4a13632e3e4d 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
231{ 231{
232 struct ath_hw *ah = common->ah; 232 struct ath_hw *ah = common->ah;
233 struct ieee80211_hdr *hdr; 233 struct ieee80211_hdr *hdr;
234 int hdrlen, padsize; 234 int hdrlen, padpos, padsize;
235 u8 keyix; 235 u8 keyix;
236 __le16 fc; 236 __le16 fc;
237 237
238 /* see if any padding is done by the hw and remove it */ 238 /* see if any padding is done by the hw and remove it */
239 hdr = (struct ieee80211_hdr *) skb->data; 239 hdr = (struct ieee80211_hdr *) skb->data;
240 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 240 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
241 padpos = 24;
241 fc = hdr->frame_control; 242 fc = hdr->frame_control;
243 if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
244 cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
245 padpos += 6; /* ETH_ALEN */
246 }
247 if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
248 cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
249 padpos += 2;
250 }
242 251
243 /* The MAC header is padded to have 32-bit boundary if the 252 /* The MAC header is padded to have 32-bit boundary if the
244 * packet payload is non-zero. The general calculation for 253 * packet payload is non-zero. The general calculation for
245 * padsize would take into account odd header lengths: 254 * padsize would take into account odd header lengths:
246 * padsize = (4 - hdrlen % 4) % 4; However, since only 255 * padsize = (4 - padpos % 4) % 4; However, since only
247 * even-length headers are used, padding can only be 0 or 2 256 * even-length headers are used, padding can only be 0 or 2
248 * bytes and we can optimize this a bit. In addition, we must 257 * bytes and we can optimize this a bit. In addition, we must
249 * not try to remove padding from short control frames that do 258 * not try to remove padding from short control frames that do
250 * not have payload. */ 259 * not have payload. */
251 padsize = hdrlen & 3; 260 padsize = padpos & 3;
252 if (padsize && hdrlen >= 24) { 261 if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
253 memmove(skb->data + padsize, skb->data, hdrlen); 262 memmove(skb->data + padsize, skb->data, padpos);
254 skb_pull(skb, padsize); 263 skb_pull(skb, padsize);
255 } 264 }
256 265