aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c19
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}
408EXPORT_SYMBOL(ath9k_cmn_key_delete); 419EXPORT_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