| 1 | --- a/drivers/net/wireless/ath/ath.h |
| 2 | +++ b/drivers/net/wireless/ath/ath.h |
| 3 | @@ -119,6 +119,7 @@ struct ath_common { |
| 4 | |
| 5 | u32 keymax; |
| 6 | DECLARE_BITMAP(keymap, ATH_KEYMAX); |
| 7 | + DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); |
| 8 | u8 splitmic; |
| 9 | |
| 10 | struct ath_regulatory regulatory; |
| 11 | --- a/drivers/net/wireless/ath/ath9k/common.c |
| 12 | +++ b/drivers/net/wireless/ath/ath9k/common.c |
| 13 | @@ -366,9 +366,13 @@ int ath9k_cmn_key_config(struct ath_comm |
| 14 | set_bit(idx, common->keymap); |
| 15 | if (key->alg == ALG_TKIP) { |
| 16 | set_bit(idx + 64, common->keymap); |
| 17 | + set_bit(idx, common->tkip_keymap); |
| 18 | + set_bit(idx + 64, common->tkip_keymap); |
| 19 | if (common->splitmic) { |
| 20 | set_bit(idx + 32, common->keymap); |
| 21 | set_bit(idx + 64 + 32, common->keymap); |
| 22 | + set_bit(idx + 32, common->tkip_keymap); |
| 23 | + set_bit(idx + 64 + 32, common->tkip_keymap); |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | @@ -393,10 +397,17 @@ void ath9k_cmn_key_delete(struct ath_com |
| 28 | return; |
| 29 | |
| 30 | clear_bit(key->hw_key_idx + 64, common->keymap); |
| 31 | + |
| 32 | + clear_bit(key->hw_key_idx, common->tkip_keymap); |
| 33 | + clear_bit(key->hw_key_idx + 64, common->tkip_keymap); |
| 34 | + |
| 35 | if (common->splitmic) { |
| 36 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); |
| 37 | clear_bit(key->hw_key_idx + 32, common->keymap); |
| 38 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); |
| 39 | + |
| 40 | + clear_bit(key->hw_key_idx + 32, common->tkip_keymap); |
| 41 | + clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); |
| 42 | } |
| 43 | } |
| 44 | EXPORT_SYMBOL(ath9k_cmn_key_delete); |
| 45 | --- a/drivers/net/wireless/ath/ath9k/recv.c |
| 46 | +++ b/drivers/net/wireless/ath/ath9k/recv.c |
| 47 | @@ -870,15 +870,18 @@ static bool ath9k_rx_accept(struct ath_c |
| 48 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
| 49 | *decrypt_error = true; |
| 50 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { |
| 51 | - if (ieee80211_is_ctl(fc)) |
| 52 | - /* |
| 53 | - * Sometimes, we get invalid |
| 54 | - * MIC failures on valid control frames. |
| 55 | - * Remove these mic errors. |
| 56 | - */ |
| 57 | - rx_stats->rs_status &= ~ATH9K_RXERR_MIC; |
| 58 | - else |
| 59 | + /* |
| 60 | + * The MIC error bit is only valid if the frame |
| 61 | + * is not a control frame or fragment, and it was |
| 62 | + * decrypted using a valid TKIP key. |
| 63 | + */ |
| 64 | + if (!ieee80211_is_ctl(fc) && |
| 65 | + !ieee80211_has_morefrags(fc) && |
| 66 | + !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && |
| 67 | + test_bit(rx_stats->rs_keyix, common->tkip_keymap)) |
| 68 | rxs->flag |= RX_FLAG_MMIC_ERROR; |
| 69 | + else |
| 70 | + rx_stats->rs_status &= ~ATH9K_RXERR_MIC; |
| 71 | } |
| 72 | /* |
| 73 | * Reject error frames with the exception of |
| 74 | --- a/drivers/net/wireless/ath/ath9k/mac.c |
| 75 | +++ b/drivers/net/wireless/ath/ath9k/mac.c |
| 76 | @@ -711,7 +711,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a |
| 77 | rs->rs_phyerr = phyerr; |
| 78 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
| 79 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
| 80 | - else if (ads.ds_rxstatus8 & AR_MichaelErr) |
| 81 | + else if ((ads.ds_rxstatus8 & AR_MichaelErr) && |
| 82 | + rs->rs_keyix != ATH9K_RXKEYIX_INVALID) |
| 83 | rs->rs_status |= ATH9K_RXERR_MIC; |
| 84 | else if (ads.ds_rxstatus8 & AR_KeyMiss) |
| 85 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
| 86 | |