diff options
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 19 |
4 files changed, 25 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index d32f2828b09..a706202fa67 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -119,6 +119,7 @@ struct ath_common { | |||
119 | 119 | ||
120 | u32 keymax; | 120 | u32 keymax; |
121 | DECLARE_BITMAP(keymap, ATH_KEYMAX); | 121 | DECLARE_BITMAP(keymap, ATH_KEYMAX); |
122 | DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); | ||
122 | u8 splitmic; | 123 | u8 splitmic; |
123 | 124 | ||
124 | struct ath_regulatory regulatory; | 125 | struct ath_regulatory regulatory; |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 31cfe468e3f..2dab64bb23a 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -372,9 +372,13 @@ int ath9k_cmn_key_config(struct ath_common *common, | |||
372 | set_bit(idx, common->keymap); | 372 | set_bit(idx, common->keymap); |
373 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { | 373 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { |
374 | set_bit(idx + 64, common->keymap); | 374 | set_bit(idx + 64, common->keymap); |
375 | set_bit(idx, common->tkip_keymap); | ||
376 | set_bit(idx + 64, common->tkip_keymap); | ||
375 | if (common->splitmic) { | 377 | if (common->splitmic) { |
376 | set_bit(idx + 32, common->keymap); | 378 | set_bit(idx + 32, common->keymap); |
377 | set_bit(idx + 64 + 32, common->keymap); | 379 | set_bit(idx + 64 + 32, common->keymap); |
380 | set_bit(idx + 32, common->tkip_keymap); | ||
381 | set_bit(idx + 64 + 32, common->tkip_keymap); | ||
378 | } | 382 | } |
379 | } | 383 | } |
380 | 384 | ||
@@ -399,10 +403,17 @@ void ath9k_cmn_key_delete(struct ath_common *common, | |||
399 | return; | 403 | return; |
400 | 404 | ||
401 | clear_bit(key->hw_key_idx + 64, common->keymap); | 405 | clear_bit(key->hw_key_idx + 64, common->keymap); |
406 | |||
407 | clear_bit(key->hw_key_idx, common->tkip_keymap); | ||
408 | clear_bit(key->hw_key_idx + 64, common->tkip_keymap); | ||
409 | |||
402 | if (common->splitmic) { | 410 | if (common->splitmic) { |
403 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); | 411 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); |
404 | clear_bit(key->hw_key_idx + 32, common->keymap); | 412 | clear_bit(key->hw_key_idx + 32, common->keymap); |
405 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | 413 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); |
414 | |||
415 | clear_bit(key->hw_key_idx + 32, common->tkip_keymap); | ||
416 | clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); | ||
406 | } | 417 | } |
407 | } | 418 | } |
408 | EXPORT_SYMBOL(ath9k_cmn_key_delete); | 419 | EXPORT_SYMBOL(ath9k_cmn_key_delete); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e955bb9d98c..0b7d1253f0c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -711,7 +711,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
711 | rs->rs_phyerr = phyerr; | 711 | rs->rs_phyerr = phyerr; |
712 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | 712 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
713 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 713 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
714 | else if (ads.ds_rxstatus8 & AR_MichaelErr) | 714 | else if ((ads.ds_rxstatus8 & AR_MichaelErr) && |
715 | rs->rs_keyix != ATH9K_RXKEYIX_INVALID) | ||
715 | rs->rs_status |= ATH9K_RXERR_MIC; | 716 | rs->rs_status |= ATH9K_RXERR_MIC; |
716 | } | 717 | } |
717 | 718 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a3fc987ebab..534a91bcc1d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -870,15 +870,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
870 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | 870 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
871 | *decrypt_error = true; | 871 | *decrypt_error = true; |
872 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | 872 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { |
873 | if (ieee80211_is_ctl(fc)) | 873 | /* |
874 | /* | 874 | * The MIC error bit is only valid if the frame |
875 | * Sometimes, we get invalid | 875 | * is not a control frame or fragment, and it was |
876 | * MIC failures on valid control frames. | 876 | * decrypted using a valid TKIP key. |
877 | * Remove these mic errors. | 877 | */ |
878 | */ | 878 | if (!ieee80211_is_ctl(fc) && |
879 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | 879 | !ieee80211_has_morefrags(fc) && |
880 | else | 880 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && |
881 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)) | ||
881 | rxs->flag |= RX_FLAG_MMIC_ERROR; | 882 | rxs->flag |= RX_FLAG_MMIC_ERROR; |
883 | else | ||
884 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | ||
882 | } | 885 | } |
883 | /* | 886 | /* |
884 | * Reject error frames with the exception of | 887 | * Reject error frames with the exception of |