ath9k_hw: fix a regression in key miss handling

The commit "ath9k_hw: Fix incorrect key_miss handling" changed the code
to only report key miss errors if a MIC error wasn't reported.
When checking the flags in that order in the MAC code, it might miss some
real events, because the value of the MIC error flag is undefined under
some conditions.

The primary issue addressed by the previous commit is making sure that
MIC errors are properly reported on the STA side. This can be fixed in
a better way by adding a separate rx status flag for key miss and
ignoring it for multicast frames.

This fix slightly improves stability in AP mode on some older hardware,
like AR9132.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 33d3079..cd272252 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -820,7 +820,8 @@
 		test_bit(rx_stats->rs_keyix, common->tkip_keymap);
 	strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
 		!(rx_stats->rs_status &
-		(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC));
+		(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
+		 ATH9K_RXERR_KEYMISS));
 
 	if (!rx_stats->rs_datalen)
 		return false;
@@ -848,6 +849,8 @@
 	 * 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;
@@ -855,7 +858,8 @@
 		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;
 		}
@@ -865,17 +869,14 @@
 		 * 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;
 	}
 
 	/*