diff options
| -rw-r--r-- | package/mac80211/patches/550-ath9k_mmic_verify.patch | 69 | 
1 files changed, 39 insertions, 30 deletions
diff --git a/package/mac80211/patches/550-ath9k_mmic_verify.patch b/package/mac80211/patches/550-ath9k_mmic_verify.patch index d280dff99..053d543cb 100644 --- a/package/mac80211/patches/550-ath9k_mmic_verify.patch +++ b/package/mac80211/patches/550-ath9k_mmic_verify.patch @@ -1,6 +1,6 @@  --- a/drivers/net/wireless/ath/ath9k/recv.c  +++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -814,16 +814,17 @@ static bool ath9k_rx_accept(struct ath_c +@@ -814,16 +814,19 @@ static bool ath9k_rx_accept(struct ath_c   			    struct ath_rx_status *rx_stats,   			    bool *decrypt_error)   { @@ -8,7 +8,7 @@  -		(rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \  -		test_bit(rx_stats->rs_keyix, common->tkip_keymap))))  - -+	bool is_mc, is_valid_tkip, mic_error = false; ++	bool is_mc, is_valid_tkip, strip_mic, mic_error = false;   	struct ath_hw *ah = common->ah;   	__le16 fc;   	u8 rx_status_len = ah->caps.rx_status_len; @@ -18,37 +18,40 @@  +	is_mc = !!is_multicast_ether_addr(hdr->addr1);  +	is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&  +		test_bit(rx_stats->rs_keyix, common->tkip_keymap); ++	strip_mic = is_valid_tkip && !(rx_stats->rs_status & ++		(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC));  +   	if (!rx_stats->rs_datalen)   		return false;           /* -@@ -853,19 +854,19 @@ static bool ath9k_rx_accept(struct ath_c - 		if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { +@@ -850,25 +853,9 @@ 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)   			*decrypt_error = true; - 		} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { +-		} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {  -			bool is_mc; - 			/* - 			 * The MIC error bit is only valid if the frame - 			 * is not a control frame or fragment, and it was +-			/* +-			 * The MIC error bit is only valid if the frame +-			 * is not a control frame or fragment, and it was  -			 * decrypted using a valid TKIP key. -+			 * decrypted using a valid TKIP key. For multicast -+			 * frames the hardware will not return a valid -+			 * key index, so accept the MIC bit for those -+			 * as well. - 			 */ +-			 */  -			is_mc = !!is_multicast_ether_addr(hdr->addr1); -- - 			if (!ieee80211_is_ctl(fc) && - 			    !ieee80211_has_morefrags(fc) && - 			    !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && +  +-			if (!ieee80211_is_ctl(fc) && +-			    !ieee80211_has_morefrags(fc) && +-			    !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&  -			    is_mc_or_valid_tkip_keyix)  -				rxs->flag |= RX_FLAG_MMIC_ERROR; -+			    (is_mc || is_valid_tkip)) -+				mic_error = true; - 			else - 				rx_stats->rs_status &= ~ATH9K_RXERR_MIC; - 		} -@@ -886,6 +887,22 @@ static bool ath9k_rx_accept(struct ath_c +-			else +-				rx_stats->rs_status &= ~ATH9K_RXERR_MIC; +-		} + 		/* + 		 * Reject error frames with the exception of + 		 * decryption and MIC failures. For monitor mode, +@@ -886,6 +873,18 @@ static bool ath9k_rx_accept(struct ath_c   			}   		}   	} @@ -59,15 +62,21 @@  +	 * False negatives are not common, so skip software verification  +	 * if the hardware considers the MIC valid.  +	 */ -+	if (is_valid_tkip && ieee80211_is_data_present(hdr->frame_control) && -+	    !(rx_stats->rs_status & (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | -+				     ATH9K_RXERR_MIC))) { -+		/* Strip the Michael MIC */ -+		rx_stats->rs_datalen -= 8; ++	if (strip_mic)  +		rxs->flag |= RX_FLAG_MMIC_STRIPPED; -+	} else if (is_mc && mic_error) { ++	else if (is_mc && mic_error)  +		rxs->flag |= RX_FLAG_MMIC_ERROR; -+	} ++   	return true;   } +@@ -1882,6 +1881,9 @@ int ath_rx_tasklet(struct ath_softc *sc, + 			ath9k_rx_skb_postprocess(common, hdr_skb, &rs, + 						 rxs, decrypt_error); +  ++		if (rxs->flag & RX_FLAG_MMIC_STRIPPED) ++			skb_trim(skb, skb->len - 8); ++ + 		/* We will now give hardware our shiny new allocated skb */ + 		bf->bf_mpdu = requeue_skb; + 		bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,  | 
