ath9k: add some extra checks to the mic failure fix
authorFelix Fietkau <nbd@openwrt.org>
Sat, 28 Aug 2010 16:23:45 +0000 (16:23 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 28 Aug 2010 16:23:45 +0000 (16:23 +0000)
SVN-Revision: 22825

package/mac80211/patches/570-ath9k_mic_failure_fix.patch

index 73c6347c5c07659f5d05eb3631beb85bced10f6b..fbd188d6fa39431fb043b3ecca5ecc253c42c9ff 100644 (file)
@@ -44,7 +44,7 @@
  EXPORT_SYMBOL(ath9k_cmn_key_delete);
 --- a/drivers/net/wireless/ath/ath9k/recv.c
 +++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -870,15 +870,19 @@ static bool ath9k_rx_accept(struct ath_c
+@@ -870,15 +870,18 @@ static bool ath9k_rx_accept(struct ath_c
                if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
                        *decrypt_error = true;
                } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
 -                      else
 +                      /*
 +                       * The MIC error bit is only valid if the frame
-+                       * is not a control frame, and it was decrypted using
-+                       * a TKIP key.
++                       * is not a control frame or fragment, and it was
++                       * decrypted using a valid TKIP key.
 +                       */
 +                      if (!ieee80211_is_ctl(fc) &&
-+                          rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
-+                          test_bit(rx_stats->rs_keyix, common->tkip_keymap)) {
++                          !ieee80211_has_morefrags(fc) &&
++                          !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
++                          test_bit(rx_stats->rs_keyix, common->tkip_keymap))
                                rxs->flag |= RX_FLAG_MMIC_ERROR;
-+                      } else {
++                      else
 +                              rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
-+                              *decrypt_error = true;
-+                      }
                }
                /*
                 * Reject error frames with the exception of
+--- 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 *a
+                       rs->rs_phyerr = phyerr;
+               } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+                       rs->rs_status |= ATH9K_RXERR_DECRYPT;
+-              else if (ads.ds_rxstatus8 & AR_MichaelErr)
++              else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
++                       rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
+                       rs->rs_status |= ATH9K_RXERR_MIC;
+               else if (ads.ds_rxstatus8 & AR_KeyMiss)
+                       rs->rs_status |= ATH9K_RXERR_DECRYPT;