Răsfoiți Sursa

ath9k: ignore invalid signal strength values in a-mpdu packets, fixes average signal strength display fluctuations

SVN-Revision: 30359
Felix Fietkau 14 ani în urmă
părinte
comite
bec8df834b

+ 44 - 0
package/mac80211/patches/580-mac80211_ignore_bad_signal_values.patch

@@ -0,0 +1,44 @@
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -659,6 +659,8 @@ ieee80211_tx_info_clear_status(struct ie
+  * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
+  * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
+  * @RX_FLAG_SHORT_GI: Short guard interval was used
++ * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
++ *	Valid only for data frames (mainly A-MPDU)
+  */
+ enum mac80211_rx_flags {
+ 	RX_FLAG_MMIC_ERROR	= 1<<0,
+@@ -672,6 +674,7 @@ enum mac80211_rx_flags {
+ 	RX_FLAG_HT		= 1<<9,
+ 	RX_FLAG_40MHZ		= 1<<10,
+ 	RX_FLAG_SHORT_GI	= 1<<11,
++	RX_FLAG_NO_SIGNAL_VAL	= 1<<12,
+ };
+ 
+ /**
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -176,7 +176,8 @@ ieee80211_add_rx_radiotap_header(struct 
+ 	pos += 2;
+ 
+ 	/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
+-	if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
++	if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM &&
++	    !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
+ 		*pos = status->signal;
+ 		rthdr->it_present |=
+ 			cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
+@@ -1309,8 +1310,10 @@ ieee80211_rx_h_sta_process(struct ieee80
+ 
+ 	sta->rx_fragments++;
+ 	sta->rx_bytes += rx->skb->len;
+-	sta->last_signal = status->signal;
+-	ewma_add(&sta->avg_signal, -status->signal);
++	if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
++		sta->last_signal = status->signal;
++		ewma_add(&sta->avg_signal, -status->signal);
++	}
+ 
+ 	if (status->chains) {
+ 		sta->chains = status->chains;

+ 37 - 0
package/mac80211/patches/581-ath9k_report_missing_signal.patch

@@ -0,0 +1,37 @@
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -954,6 +954,7 @@ static void ath9k_process_rssi(struct at
+ 	struct ath_softc *sc = hw->priv;
+ 	struct ath_hw *ah = common->ah;
+ 	int last_rssi;
++	int rssi = rx_stats->rs_rssi;
+ 
+ 	if (!rx_stats->is_mybeacon ||
+ 	    ((ah->opmode != NL80211_IFTYPE_STATION) &&
+@@ -965,13 +966,12 @@ static void ath9k_process_rssi(struct at
+ 
+ 	last_rssi = sc->last_rssi;
+ 	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+-		rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
+-					      ATH_RSSI_EP_MULTIPLIER);
+-	if (rx_stats->rs_rssi < 0)
+-		rx_stats->rs_rssi = 0;
++		rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
++	if (rssi < 0)
++		rssi = 0;
+ 
+ 	/* Update Beacon RSSI, this is used by ANI. */
+-	ah->stats.avgbrssi = rx_stats->rs_rssi;
++	ah->stats.avgbrssi = rssi;
+ }
+ 
+ /*
+@@ -1012,6 +1012,8 @@ static int ath9k_rx_skb_preprocess(struc
+ 	rx_status->signal = ah->noise + rx_stats->rs_rssi;
+ 	rx_status->antenna = rx_stats->rs_antenna;
+ 	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
++	if (rx_stats->rs_moreaggr)
++		rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
+ 
+ 	for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
+ 		s8 rssi;