diff options
author | Felix Fietkau <nbd@openwrt.org> | 2008-10-05 12:05:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-06 18:14:57 -0400 |
commit | 2f7fe87034298d94301315ba4bb65c7284c709d0 (patch) | |
tree | e8583ae3686a243405b77d4ef6498bc4199ca3a2 /drivers/net/wireless/ath5k/base.c | |
parent | 870abdf67170daa9f1022e55a35c469239fcc74c (diff) |
ath5k: implement multi-rate retry support, fix tx status reporting
Clean up the tx status reporting, fix retry counters (short retries are
virtual collisions, not actual retries). Implement multi-rate retry
support.
This also fixes strong throughput fluctuations with rc80211_pid
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 47be49acf55e..9b95c4049b31 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -541,6 +541,12 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
541 | goto err_irq; | 541 | goto err_irq; |
542 | } | 542 | } |
543 | 543 | ||
544 | /* set up multi-rate retry capabilities */ | ||
545 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
546 | hw->max_altrates = 3; | ||
547 | hw->max_altrate_tries = 11; | ||
548 | } | ||
549 | |||
544 | /* Finish private driver data initialization */ | 550 | /* Finish private driver data initialization */ |
545 | ret = ath5k_attach(pdev, hw); | 551 | ret = ath5k_attach(pdev, hw); |
546 | if (ret) | 552 | if (ret) |
@@ -1173,7 +1179,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1173 | struct sk_buff *skb = bf->skb; | 1179 | struct sk_buff *skb = bf->skb; |
1174 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1180 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1175 | unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; | 1181 | unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; |
1176 | int ret; | 1182 | struct ieee80211_rate *rate; |
1183 | unsigned int mrr_rate[3], mrr_tries[3]; | ||
1184 | int i, ret; | ||
1177 | 1185 | ||
1178 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; | 1186 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; |
1179 | 1187 | ||
@@ -1198,6 +1206,22 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1198 | if (ret) | 1206 | if (ret) |
1199 | goto err_unmap; | 1207 | goto err_unmap; |
1200 | 1208 | ||
1209 | memset(mrr_rate, 0, sizeof(mrr_rate)); | ||
1210 | memset(mrr_tries, 0, sizeof(mrr_tries)); | ||
1211 | for (i = 0; i < 3; i++) { | ||
1212 | rate = ieee80211_get_alt_retry_rate(sc->hw, info, i); | ||
1213 | if (!rate) | ||
1214 | break; | ||
1215 | |||
1216 | mrr_rate[i] = rate->hw_value; | ||
1217 | mrr_tries[i] = info->control.retries[i].limit; | ||
1218 | } | ||
1219 | |||
1220 | ah->ah_setup_mrr_tx_desc(ah, ds, | ||
1221 | mrr_rate[0], mrr_tries[0], | ||
1222 | mrr_rate[1], mrr_tries[1], | ||
1223 | mrr_rate[2], mrr_tries[2]); | ||
1224 | |||
1201 | ds->ds_link = 0; | 1225 | ds->ds_link = 0; |
1202 | ds->ds_data = bf->skbaddr; | 1226 | ds->ds_data = bf->skbaddr; |
1203 | 1227 | ||
@@ -1814,7 +1838,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1814 | struct ath5k_desc *ds; | 1838 | struct ath5k_desc *ds; |
1815 | struct sk_buff *skb; | 1839 | struct sk_buff *skb; |
1816 | struct ieee80211_tx_info *info; | 1840 | struct ieee80211_tx_info *info; |
1817 | int ret; | 1841 | int i, ret; |
1818 | 1842 | ||
1819 | spin_lock(&txq->lock); | 1843 | spin_lock(&txq->lock); |
1820 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1844 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
@@ -1836,7 +1860,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1836 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | 1860 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, |
1837 | PCI_DMA_TODEVICE); | 1861 | PCI_DMA_TODEVICE); |
1838 | 1862 | ||
1839 | info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6; | 1863 | memset(&info->status, 0, sizeof(info->status)); |
1864 | info->tx_rate_idx = ath5k_hw_to_driver_rix(sc, | ||
1865 | ts.ts_rate[ts.ts_final_idx]); | ||
1866 | info->status.retry_count = ts.ts_longretry; | ||
1867 | |||
1868 | for (i = 0; i < 4; i++) { | ||
1869 | struct ieee80211_tx_altrate *r = | ||
1870 | &info->status.retries[i]; | ||
1871 | |||
1872 | if (ts.ts_rate[i]) { | ||
1873 | r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); | ||
1874 | r->limit = ts.ts_retry[i]; | ||
1875 | } else { | ||
1876 | r->rate_idx = -1; | ||
1877 | r->limit = 0; | ||
1878 | } | ||
1879 | } | ||
1880 | |||
1881 | info->status.excessive_retries = 0; | ||
1840 | if (unlikely(ts.ts_status)) { | 1882 | if (unlikely(ts.ts_status)) { |
1841 | sc->ll_stats.dot11ACKFailureCount++; | 1883 | sc->ll_stats.dot11ACKFailureCount++; |
1842 | if (ts.ts_status & AR5K_TXERR_XRETRY) | 1884 | if (ts.ts_status & AR5K_TXERR_XRETRY) |