summaryrefslogtreecommitdiffstats
path: root/package
diff options
context:
space:
mode:
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2011-09-17 08:34:37 +0000
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2011-09-17 08:34:37 +0000
commit9618831a6404c29557f248472979776c4e7bf5bb (patch)
treec89eb6fd43d69ae68b671a88f5823a491465baab /package
parentbba0668cb09da4376d834ea7eb0f8f5190c6d7e2 (diff)
ath9k: fix a regression in handling of MAC key miss events (should improve connection stability)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@28250 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package')
-rw-r--r--package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch83
1 files changed, 83 insertions, 0 deletions
diff --git a/package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch b/package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch
new file mode 100644
index 000000000..66ea9a7c0
--- /dev/null
+++ b/package/mac80211/patches/551-ath9k_fix_keymiss_handling.patch
@@ -0,0 +1,83 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+@@ -525,8 +525,8 @@ int ath9k_hw_process_rxdesc_edma(struct
+ rxs->rs_status |= ATH9K_RXERR_DECRYPT;
+ else if (rxsp->status11 & AR_MichaelErr)
+ rxs->rs_status |= ATH9K_RXERR_MIC;
+- else if (rxsp->status11 & AR_KeyMiss)
+- rxs->rs_status |= ATH9K_RXERR_DECRYPT;
++ if (rxsp->status11 & AR_KeyMiss)
++ rxs->rs_status |= ATH9K_RXERR_KEYMISS;
+ }
+
+ return 0;
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -620,8 +620,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
+ rs->rs_status |= ATH9K_RXERR_DECRYPT;
+ else if (ads.ds_rxstatus8 & AR_MichaelErr)
+ rs->rs_status |= ATH9K_RXERR_MIC;
+- else if (ads.ds_rxstatus8 & AR_KeyMiss)
+- rs->rs_status |= ATH9K_RXERR_DECRYPT;
++ if (ads.ds_rxstatus8 & AR_KeyMiss)
++ rs->rs_status |= ATH9K_RXERR_KEYMISS;
+ }
+
+ return 0;
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -181,6 +181,7 @@ struct ath_htc_rx_status {
+ #define ATH9K_RXERR_FIFO 0x04
+ #define ATH9K_RXERR_DECRYPT 0x08
+ #define ATH9K_RXERR_MIC 0x10
++#define ATH9K_RXERR_KEYMISS 0x20
+
+ #define ATH9K_RX_MORE 0x01
+ #define ATH9K_RX_MORE_AGGR 0x02
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -854,6 +854,8 @@ static bool ath9k_rx_accept(struct ath_c
+ * descriptors.
+ */
+ if (rx_stats->rs_status != 0) {
++ u8 status_mask;
++
+ if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
+ rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
+ mic_error = false;
+@@ -861,7 +863,8 @@ static bool ath9k_rx_accept(struct ath_c
+ if (rx_stats->rs_status & ATH9K_RXERR_PHY)
+ return false;
+
+- if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
++ if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) ||
++ (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) {
+ *decrypt_error = true;
+ mic_error = false;
+ }
+@@ -871,17 +874,14 @@ static bool ath9k_rx_accept(struct ath_c
+ * decryption and MIC failures. For monitor mode,
+ * we also ignore the CRC error.
+ */
+- if (ah->is_monitoring) {
+- if (rx_stats->rs_status &
+- ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
+- ATH9K_RXERR_CRC))
+- return false;
+- } else {
+- if (rx_stats->rs_status &
+- ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
+- return false;
+- }
+- }
++ status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
++ ATH9K_RXERR_KEYMISS;
++
++ if (ah->is_monitoring)
++ status_mask |= ATH9K_RXERR_CRC;
++
++ if (rx_stats->rs_status & ~status_mask)
++ return false;
+ }
+
+ /*