diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-07-22 17:51:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-22 17:51:16 -0400 |
commit | 41bf37117b47fc5ce2aae91f6a108e7e42e0b046 (patch) | |
tree | d5c8f24075313edfe548256dd931527f1569921e /drivers/net/wireless/ath/ath9k/recv.c | |
parent | 415b3334a21aa67806c52d1acf4e72e14f7f402f (diff) | |
parent | 6e6e8c510a84fe3237ef02b954e58cca6a3f4b1a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 70dc8ecdad4d..9a4850154fb2 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -815,16 +815,19 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
815 | struct ath_rx_status *rx_stats, | 815 | struct ath_rx_status *rx_stats, |
816 | bool *decrypt_error) | 816 | bool *decrypt_error) |
817 | { | 817 | { |
818 | #define is_mc_or_valid_tkip_keyix ((is_mc || \ | 818 | bool is_mc, is_valid_tkip, strip_mic, mic_error; |
819 | (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \ | ||
820 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)))) | ||
821 | |||
822 | struct ath_hw *ah = common->ah; | 819 | struct ath_hw *ah = common->ah; |
823 | __le16 fc; | 820 | __le16 fc; |
824 | u8 rx_status_len = ah->caps.rx_status_len; | 821 | u8 rx_status_len = ah->caps.rx_status_len; |
825 | 822 | ||
826 | fc = hdr->frame_control; | 823 | fc = hdr->frame_control; |
827 | 824 | ||
825 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
826 | is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && | ||
827 | test_bit(rx_stats->rs_keyix, common->tkip_keymap); | ||
828 | strip_mic = is_valid_tkip && !(rx_stats->rs_status & | ||
829 | (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC)); | ||
830 | |||
828 | if (!rx_stats->rs_datalen) | 831 | if (!rx_stats->rs_datalen) |
829 | return false; | 832 | return false; |
830 | /* | 833 | /* |
@@ -839,6 +842,11 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
839 | if (rx_stats->rs_more) | 842 | if (rx_stats->rs_more) |
840 | return true; | 843 | return true; |
841 | 844 | ||
845 | mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) && | ||
846 | !ieee80211_has_morefrags(fc) && | ||
847 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | ||
848 | (rx_stats->rs_status & ATH9K_RXERR_MIC); | ||
849 | |||
842 | /* | 850 | /* |
843 | * The rx_stats->rs_status will not be set until the end of the | 851 | * The rx_stats->rs_status will not be set until the end of the |
844 | * chained descriptors so it can be ignored if rs_more is set. The | 852 | * chained descriptors so it can be ignored if rs_more is set. The |
@@ -846,30 +854,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
846 | * descriptors. | 854 | * descriptors. |
847 | */ | 855 | */ |
848 | if (rx_stats->rs_status != 0) { | 856 | if (rx_stats->rs_status != 0) { |
849 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) | 857 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) { |
850 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | 858 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; |
859 | mic_error = false; | ||
860 | } | ||
851 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) | 861 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) |
852 | return false; | 862 | return false; |
853 | 863 | ||
854 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | 864 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
855 | *decrypt_error = true; | 865 | *decrypt_error = true; |
856 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | 866 | mic_error = false; |
857 | bool is_mc; | ||
858 | /* | ||
859 | * The MIC error bit is only valid if the frame | ||
860 | * is not a control frame or fragment, and it was | ||
861 | * decrypted using a valid TKIP key. | ||
862 | */ | ||
863 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
864 | |||
865 | if (!ieee80211_is_ctl(fc) && | ||
866 | !ieee80211_has_morefrags(fc) && | ||
867 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | ||
868 | is_mc_or_valid_tkip_keyix) | ||
869 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
870 | else | ||
871 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | ||
872 | } | 867 | } |
868 | |||
873 | /* | 869 | /* |
874 | * Reject error frames with the exception of | 870 | * Reject error frames with the exception of |
875 | * decryption and MIC failures. For monitor mode, | 871 | * decryption and MIC failures. For monitor mode, |
@@ -887,6 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
887 | } | 883 | } |
888 | } | 884 | } |
889 | } | 885 | } |
886 | |||
887 | /* | ||
888 | * For unicast frames the MIC error bit can have false positives, | ||
889 | * so all MIC error reports need to be validated in software. | ||
890 | * False negatives are not common, so skip software verification | ||
891 | * if the hardware considers the MIC valid. | ||
892 | */ | ||
893 | if (strip_mic) | ||
894 | rxs->flag |= RX_FLAG_MMIC_STRIPPED; | ||
895 | else if (is_mc && mic_error) | ||
896 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
897 | |||
890 | return true; | 898 | return true; |
891 | } | 899 | } |
892 | 900 | ||
@@ -1939,6 +1947,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1939 | sc->rx.rxotherant = 0; | 1947 | sc->rx.rxotherant = 0; |
1940 | } | 1948 | } |
1941 | 1949 | ||
1950 | if (rxs->flag & RX_FLAG_MMIC_STRIPPED) | ||
1951 | skb_trim(skb, skb->len - 8); | ||
1952 | |||
1942 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 1953 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
1943 | 1954 | ||
1944 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | | 1955 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | |