diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3abefb580a47..8b7489d61d38 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -316,6 +316,55 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | 318 | ||
319 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | ||
320 | struct sk_buff *skb, | ||
321 | struct ath_rx_status *rx_stats, | ||
322 | struct ieee80211_rx_status *rxs, | ||
323 | bool decrypt_error) | ||
324 | { | ||
325 | struct ath_hw *ah = common->ah; | ||
326 | struct ieee80211_hdr *hdr; | ||
327 | int hdrlen, padsize; | ||
328 | u8 keyix; | ||
329 | __le16 fc; | ||
330 | |||
331 | /* see if any padding is done by the hw and remove it */ | ||
332 | hdr = (struct ieee80211_hdr *) skb->data; | ||
333 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
334 | fc = hdr->frame_control; | ||
335 | |||
336 | /* The MAC header is padded to have 32-bit boundary if the | ||
337 | * packet payload is non-zero. The general calculation for | ||
338 | * padsize would take into account odd header lengths: | ||
339 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
340 | * even-length headers are used, padding can only be 0 or 2 | ||
341 | * bytes and we can optimize this a bit. In addition, we must | ||
342 | * not try to remove padding from short control frames that do | ||
343 | * not have payload. */ | ||
344 | padsize = hdrlen & 3; | ||
345 | if (padsize && hdrlen >= 24) { | ||
346 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
347 | skb_pull(skb, padsize); | ||
348 | } | ||
349 | |||
350 | keyix = rx_stats->rs_keyix; | ||
351 | |||
352 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { | ||
353 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
354 | } else if (ieee80211_has_protected(fc) | ||
355 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
356 | keyix = skb->data[hdrlen + 3] >> 6; | ||
357 | |||
358 | if (test_bit(keyix, common->keymap)) | ||
359 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
360 | } | ||
361 | if (ah->sw_mgmt_crypto && | ||
362 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
363 | ieee80211_is_mgmt(fc)) | ||
364 | /* Use software decrypt for management frames. */ | ||
365 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
366 | } | ||
367 | |||
319 | static void ath_opmode_init(struct ath_softc *sc) | 368 | static void ath_opmode_init(struct ath_softc *sc) |
320 | { | 369 | { |
321 | struct ath_hw *ah = sc->sc_ah; | 370 | struct ath_hw *ah = sc->sc_ah; |
@@ -716,10 +765,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
716 | */ | 765 | */ |
717 | struct ieee80211_hw *hw = NULL; | 766 | struct ieee80211_hw *hw = NULL; |
718 | struct ieee80211_hdr *hdr; | 767 | struct ieee80211_hdr *hdr; |
719 | int hdrlen, padsize, retval; | 768 | int retval; |
720 | bool decrypt_error = false; | 769 | bool decrypt_error = false; |
721 | u8 keyix; | ||
722 | __le16 fc; | ||
723 | 770 | ||
724 | spin_lock_bh(&sc->rx.rxbuflock); | 771 | spin_lock_bh(&sc->rx.rxbuflock); |
725 | 772 | ||
@@ -830,40 +877,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
830 | 877 | ||
831 | skb_put(skb, rx_stats->rs_datalen); | 878 | skb_put(skb, rx_stats->rs_datalen); |
832 | 879 | ||
833 | /* see if any padding is done by the hw and remove it */ | 880 | ath9k_rx_skb_postprocess(common, skb, rx_stats, |
834 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 881 | rxs, decrypt_error); |
835 | fc = hdr->frame_control; | ||
836 | |||
837 | /* The MAC header is padded to have 32-bit boundary if the | ||
838 | * packet payload is non-zero. The general calculation for | ||
839 | * padsize would take into account odd header lengths: | ||
840 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
841 | * even-length headers are used, padding can only be 0 or 2 | ||
842 | * bytes and we can optimize this a bit. In addition, we must | ||
843 | * not try to remove padding from short control frames that do | ||
844 | * not have payload. */ | ||
845 | padsize = hdrlen & 3; | ||
846 | if (padsize && hdrlen >= 24) { | ||
847 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
848 | skb_pull(skb, padsize); | ||
849 | } | ||
850 | |||
851 | keyix = rx_stats->rs_keyix; | ||
852 | |||
853 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { | ||
854 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
855 | } else if (ieee80211_has_protected(fc) | ||
856 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
857 | keyix = skb->data[hdrlen + 3] >> 6; | ||
858 | |||
859 | if (test_bit(keyix, common->keymap)) | ||
860 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
861 | } | ||
862 | if (ah->sw_mgmt_crypto && | ||
863 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
864 | ieee80211_is_mgmt(fc)) | ||
865 | /* Use software decrypt for management frames. */ | ||
866 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
867 | 882 | ||
868 | /* We will now give hardware our shiny new allocated skb */ | 883 | /* We will now give hardware our shiny new allocated skb */ |
869 | bf->bf_mpdu = requeue_skb; | 884 | bf->bf_mpdu = requeue_skb; |