aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-04-09 15:37:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:58:59 -0400
commit6d7b97b23e114c8fbb825e6721164d228c1af3fc (patch)
tree8682f55f680c4272c24dcad4b47d241a76c25e52 /drivers/net/wireless/ath/ath5k
parenta065784620a2b78a2bbd00e066c004644d227ea8 (diff)
ath5k: fix tx status reporting issues
During normal operation, minstrel was showing suspicious EWMA probabilities exceeding 100%. It looks like the tx status reporting in ath5k was not properly clearing the rate index for rates which were never attempted. This is caused by uninitialized stale data in the on-stack tx status information, which is reused when more frames are received. To fix this, rely on ts->ts_final_idx to select the last attempted rate, instead of checking whether ts->ts_rate is set. Additionally, the conversion from the driver rate index back to the mac80211 rate index can be dropped, as the mac80211 tx status will still have the original rate index which was used to set up the descriptor. Additionally, one more inaccuracy was fixed - the final rate attempt count only needs to be increased by one if the transmission attempt was successful. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4d7f21ee111..753662f98f7 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1580,21 +1580,14 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
1580 info = IEEE80211_SKB_CB(skb); 1580 info = IEEE80211_SKB_CB(skb);
1581 1581
1582 ieee80211_tx_info_clear_status(info); 1582 ieee80211_tx_info_clear_status(info);
1583 for (i = 0; i < 4; i++) { 1583 for (i = 0; i <= ts->ts_final_idx; i++) {
1584 struct ieee80211_tx_rate *r = 1584 struct ieee80211_tx_rate *r =
1585 &info->status.rates[i]; 1585 &info->status.rates[i];
1586 1586
1587 if (ts->ts_rate[i]) { 1587 r->count = ts->ts_retry[i];
1588 r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]);
1589 r->count = ts->ts_retry[i];
1590 } else {
1591 r->idx = -1;
1592 r->count = 0;
1593 }
1594 } 1588 }
1595 1589
1596 /* count the successful attempt as well */ 1590 info->status.rates[ts->ts_final_idx + 1].idx = -1;
1597 info->status.rates[ts->ts_final_idx].count++;
1598 1591
1599 if (unlikely(ts->ts_status)) { 1592 if (unlikely(ts->ts_status)) {
1600 sc->stats.ack_fail++; 1593 sc->stats.ack_fail++;
@@ -1609,6 +1602,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
1609 } else { 1602 } else {
1610 info->flags |= IEEE80211_TX_STAT_ACK; 1603 info->flags |= IEEE80211_TX_STAT_ACK;
1611 info->status.ack_signal = ts->ts_rssi; 1604 info->status.ack_signal = ts->ts_rssi;
1605
1606 /* count the successful attempt as well */
1607 info->status.rates[ts->ts_final_idx].count++;
1612 } 1608 }
1613 1609
1614 /* 1610 /*