Browse Source

ath5k: support for FIF_FCSFAIL filter

When the FIF_FCSFAIL filter flag is set, pass frames with CRC errors.

Signed-off-by: Mathy Vanhoef <vanhoefm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Mathy Vanhoef 11 years ago
parent
commit
41881354f9

+ 1 - 0
drivers/net/wireless/ath/ath5k/ath5k.h

@@ -1285,6 +1285,7 @@ struct ath5k_hw {
 #define ATH_STAT_STARTED	3		/* opened & irqs enabled */
 #define ATH_STAT_STARTED	3		/* opened & irqs enabled */
 
 
 	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
 	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
+	unsigned int		fif_filter_flags; /* Current FIF_* filter flags */
 	struct ieee80211_channel *curchan;	/* current h/w channel */
 	struct ieee80211_channel *curchan;	/* current h/w channel */
 
 
 	u16			nvifs;
 	u16			nvifs;

+ 14 - 2
drivers/net/wireless/ath/ath5k/base.c

@@ -1382,6 +1382,9 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
 	rxs->flag = 0;
 	rxs->flag = 0;
 	if (unlikely(rs->rs_status & AR5K_RXERR_MIC))
 	if (unlikely(rs->rs_status & AR5K_RXERR_MIC))
 		rxs->flag |= RX_FLAG_MMIC_ERROR;
 		rxs->flag |= RX_FLAG_MMIC_ERROR;
+	if (unlikely(rs->rs_status & AR5K_RXERR_CRC))
+		rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
+
 
 
 	/*
 	/*
 	 * always extend the mac timestamp, since this information is
 	 * always extend the mac timestamp, since this information is
@@ -1449,6 +1452,8 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
 	ah->stats.rx_bytes_count += rs->rs_datalen;
 	ah->stats.rx_bytes_count += rs->rs_datalen;
 
 
 	if (unlikely(rs->rs_status)) {
 	if (unlikely(rs->rs_status)) {
+		unsigned int filters;
+
 		if (rs->rs_status & AR5K_RXERR_CRC)
 		if (rs->rs_status & AR5K_RXERR_CRC)
 			ah->stats.rxerr_crc++;
 			ah->stats.rxerr_crc++;
 		if (rs->rs_status & AR5K_RXERR_FIFO)
 		if (rs->rs_status & AR5K_RXERR_FIFO)
@@ -1480,8 +1485,15 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
 			return true;
 			return true;
 		}
 		}
 
 
-		/* reject any frames with non-crypto errors */
-		if (rs->rs_status & ~(AR5K_RXERR_DECRYPT))
+		/*
+		 * Reject any frames with non-crypto errors, and take into account the
+		 * current FIF_* filters.
+		 */
+		filters = AR5K_RXERR_DECRYPT;
+		if (ah->fif_filter_flags & FIF_FCSFAIL)
+			filters |= AR5K_RXERR_CRC;
+
+		if (rs->rs_status & ~filters)
 			return false;
 			return false;
 	}
 	}
 
 

+ 2 - 0
drivers/net/wireless/ath/ath5k/mac80211-ops.c

@@ -473,6 +473,8 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 	/* Set the cached hw filter flags, this will later actually
 	/* Set the cached hw filter flags, this will later actually
 	 * be set in HW */
 	 * be set in HW */
 	ah->filter_flags = rfilt;
 	ah->filter_flags = rfilt;
+	/* Store current FIF filter flags */
+	ah->fif_filter_flags = *new_flags;
 
 
 	mutex_unlock(&ah->lock);
 	mutex_unlock(&ah->lock);
 }
 }