aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2009-03-20 05:57:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:03 -0400
commit8a92e2ee02dee127d309c73969aeb2a56567c9a0 (patch)
tree41b86c20c44424b35185319ee55881a22bd16736 /drivers
parent827b1fb44b7e41377a5498b9d070a11dfae2c283 (diff)
ath9k: Fix bug in reporting status of tx rate
This patch updates count of every hw tried rate with appropriate tries before reporting tx status of a frame. Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath9k/xmit.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index f2877193e958..21e90bca3501 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -67,7 +67,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
67static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 67static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
68 int txok); 68 int txok);
69static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 69static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
70 int nbad, int txok); 70 int nbad, int txok, bool update_rc);
71 71
72/*********************/ 72/*********************/
73/* Aggregation logic */ 73/* Aggregation logic */
@@ -370,11 +370,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
370 ath_tx_update_baw(sc, tid, bf->bf_seqno); 370 ath_tx_update_baw(sc, tid, bf->bf_seqno);
371 spin_unlock_bh(&txq->axq_lock); 371 spin_unlock_bh(&txq->axq_lock);
372 372
373 if (rc_update) 373 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
374 if (acked_cnt == 1 || txfail_cnt == 1) { 374 ath_tx_rc_status(bf, ds, nbad, txok, true);
375 ath_tx_rc_status(bf, ds, nbad, txok); 375 rc_update = false;
376 rc_update = false; 376 } else {
377 } 377 ath_tx_rc_status(bf, ds, nbad, txok, false);
378 }
379
378 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); 380 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
379 } else { 381 } else {
380 /* retry the un-acked ones */ 382 /* retry the un-acked ones */
@@ -1779,8 +1781,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1779 tx_info->flags |= IEEE80211_TX_STAT_ACK; 1781 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1780 } 1782 }
1781 1783
1782 tx_info->status.rates[0].count = tx_status->retries + 1;
1783
1784 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1784 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1785 padsize = hdrlen & 3; 1785 padsize = hdrlen & 3;
1786 if (padsize && hdrlen >= 24) { 1786 if (padsize && hdrlen >= 24) {
@@ -1867,30 +1867,39 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1867} 1867}
1868 1868
1869static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 1869static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1870 int nbad, int txok) 1870 int nbad, int txok, bool update_rc)
1871{ 1871{
1872 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 1872 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
1873 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1873 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1874 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1874 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1875 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 1875 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1876 struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
1877 u8 i, tx_rateindex;
1876 1878
1877 if (txok) 1879 if (txok)
1878 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi; 1880 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
1879 1881
1880 tx_info_priv->update_rc = false; 1882 tx_rateindex = ds->ds_txstat.ts_rateindex;
1883 WARN_ON(tx_rateindex >= hw->max_rates);
1884
1885 tx_info_priv->update_rc = update_rc;
1881 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) 1886 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1882 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 1887 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1883 1888
1884 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 1889 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1885 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { 1890 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1886 if (ieee80211_is_data(hdr->frame_control)) { 1891 if (ieee80211_is_data(hdr->frame_control)) {
1887 memcpy(&tx_info_priv->tx, &ds->ds_txstat, 1892 memcpy(&tx_info_priv->tx, &ds->ds_txstat,
1888 sizeof(tx_info_priv->tx)); 1893 sizeof(tx_info_priv->tx));
1889 tx_info_priv->n_frames = bf->bf_nframes; 1894 tx_info_priv->n_frames = bf->bf_nframes;
1890 tx_info_priv->n_bad_frames = nbad; 1895 tx_info_priv->n_bad_frames = nbad;
1891 tx_info_priv->update_rc = true;
1892 } 1896 }
1893 } 1897 }
1898
1899 for (i = tx_rateindex + 1; i < hw->max_rates; i++)
1900 tx_info->status.rates[i].count = 0;
1901
1902 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
1894} 1903}
1895 1904
1896static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) 1905static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
@@ -2009,7 +2018,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2009 bf->bf_retries = ds->ds_txstat.ts_longretry; 2018 bf->bf_retries = ds->ds_txstat.ts_longretry;
2010 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 2019 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
2011 bf->bf_state.bf_type |= BUF_XRETRY; 2020 bf->bf_state.bf_type |= BUF_XRETRY;
2012 ath_tx_rc_status(bf, ds, 0, txok); 2021 ath_tx_rc_status(bf, ds, 0, txok, true);
2013 } 2022 }
2014 2023
2015 if (bf_isampdu(bf)) 2024 if (bf_isampdu(bf))