]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.36.2/ath9k-fix-spurious-mic-failure-reports.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.2 / ath9k-fix-spurious-mic-failure-reports.patch
CommitLineData
c06f7f46
GKH
1From 56363ddeeed3afc5277ca227209773bc1042cc7b Mon Sep 17 00:00:00 2001
2From: Felix Fietkau <nbd@openwrt.org>
3Date: Sat, 28 Aug 2010 18:21:21 +0200
4Subject: ath9k: fix spurious MIC failure reports
5
6From: Felix Fietkau <nbd@openwrt.org>
7
8commit 56363ddeeed3afc5277ca227209773bc1042cc7b upstream.
9
10According to the hardware documentation, the MIC failure bit is only
11valid if the frame was decrypted using a valid TKIP key and is not a
12fragment.
13In some setups I've seen hardware-reported MIC failures on an AP that
14was configured for CCMP only, so it's clear that additional checks are
15necessary.
16
17Signed-off-by: Felix Fietkau <nbd@openwrt.org>
18Signed-off-by: John W. Linville <linville@tuxdriver.com>
19Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
20
21---
22 drivers/net/wireless/ath/ath.h | 1 +
23 drivers/net/wireless/ath/ath9k/common.c | 11 +++++++++++
24 drivers/net/wireless/ath/ath9k/mac.c | 3 ++-
25 drivers/net/wireless/ath/ath9k/recv.c | 19 +++++++++++--------
26 4 files changed, 25 insertions(+), 9 deletions(-)
27
28--- a/drivers/net/wireless/ath/ath.h
29+++ b/drivers/net/wireless/ath/ath.h
30@@ -119,6 +119,7 @@ struct ath_common {
31
32 u32 keymax;
33 DECLARE_BITMAP(keymap, ATH_KEYMAX);
34+ DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
35 u8 splitmic;
36
37 struct ath_regulatory regulatory;
38--- a/drivers/net/wireless/ath/ath9k/common.c
39+++ b/drivers/net/wireless/ath/ath9k/common.c
40@@ -366,9 +366,13 @@ int ath9k_cmn_key_config(struct ath_comm
41 set_bit(idx, common->keymap);
42 if (key->alg == ALG_TKIP) {
43 set_bit(idx + 64, common->keymap);
44+ set_bit(idx, common->tkip_keymap);
45+ set_bit(idx + 64, common->tkip_keymap);
46 if (common->splitmic) {
47 set_bit(idx + 32, common->keymap);
48 set_bit(idx + 64 + 32, common->keymap);
49+ set_bit(idx + 32, common->tkip_keymap);
50+ set_bit(idx + 64 + 32, common->tkip_keymap);
51 }
52 }
53
54@@ -393,10 +397,17 @@ void ath9k_cmn_key_delete(struct ath_com
55 return;
56
57 clear_bit(key->hw_key_idx + 64, common->keymap);
58+
59+ clear_bit(key->hw_key_idx, common->tkip_keymap);
60+ clear_bit(key->hw_key_idx + 64, common->tkip_keymap);
61+
62 if (common->splitmic) {
63 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
64 clear_bit(key->hw_key_idx + 32, common->keymap);
65 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
66+
67+ clear_bit(key->hw_key_idx + 32, common->tkip_keymap);
68+ clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap);
69 }
70 }
71 EXPORT_SYMBOL(ath9k_cmn_key_delete);
72--- a/drivers/net/wireless/ath/ath9k/mac.c
73+++ b/drivers/net/wireless/ath/ath9k/mac.c
74@@ -711,7 +711,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
75 rs->rs_phyerr = phyerr;
76 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
77 rs->rs_status |= ATH9K_RXERR_DECRYPT;
78- else if (ads.ds_rxstatus8 & AR_MichaelErr)
79+ else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
80+ rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
81 rs->rs_status |= ATH9K_RXERR_MIC;
82 else if (ads.ds_rxstatus8 & AR_KeyMiss)
83 rs->rs_status |= ATH9K_RXERR_DECRYPT;
84--- a/drivers/net/wireless/ath/ath9k/recv.c
85+++ b/drivers/net/wireless/ath/ath9k/recv.c
86@@ -870,15 +870,18 @@ static bool ath9k_rx_accept(struct ath_c
87 if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
88 *decrypt_error = true;
89 } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
90- if (ieee80211_is_ctl(fc))
91- /*
92- * Sometimes, we get invalid
93- * MIC failures on valid control frames.
94- * Remove these mic errors.
95- */
96- rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
97- else
98+ /*
99+ * The MIC error bit is only valid if the frame
100+ * is not a control frame or fragment, and it was
101+ * decrypted using a valid TKIP key.
102+ */
103+ if (!ieee80211_is_ctl(fc) &&
104+ !ieee80211_has_morefrags(fc) &&
105+ !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
106+ test_bit(rx_stats->rs_keyix, common->tkip_keymap))
107 rxs->flag |= RX_FLAG_MMIC_ERROR;
108+ else
109+ rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
110 }
111 /*
112 * Reject error frames with the exception of