aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath9k/xmit.c78
1 files changed, 46 insertions, 32 deletions
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index e3f376611f85..689bdbf78808 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 Atheros Communications Inc. 2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -64,6 +64,10 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
64static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 64static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
65 struct list_head *head); 65 struct list_head *head);
66static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); 66static 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,
68 int txok);
69static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
70 int nbad, int txok, bool update_rc);
67 71
68/*********************/ 72/*********************/
69/* Aggregation logic */ 73/* Aggregation logic */
@@ -274,9 +278,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
274 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 278 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
275 struct ath_desc *ds = bf_last->bf_desc; 279 struct ath_desc *ds = bf_last->bf_desc;
276 struct list_head bf_head, bf_pending; 280 struct list_head bf_head, bf_pending;
277 u16 seq_st = 0; 281 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
278 u32 ba[WME_BA_BMP_SIZE >> 5]; 282 u32 ba[WME_BA_BMP_SIZE >> 5];
279 int isaggr, txfail, txpending, sendbar = 0, needreset = 0; 283 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
284 bool rc_update = true;
280 285
281 skb = (struct sk_buff *)bf->bf_mpdu; 286 skb = (struct sk_buff *)bf->bf_mpdu;
282 hdr = (struct ieee80211_hdr *)skb->data; 287 hdr = (struct ieee80211_hdr *)skb->data;
@@ -316,6 +321,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
316 INIT_LIST_HEAD(&bf_pending); 321 INIT_LIST_HEAD(&bf_pending);
317 INIT_LIST_HEAD(&bf_head); 322 INIT_LIST_HEAD(&bf_head);
318 323
324 nbad = ath_tx_num_badfrms(sc, bf, txok);
319 while (bf) { 325 while (bf) {
320 txfail = txpending = 0; 326 txfail = txpending = 0;
321 bf_next = bf->bf_next; 327 bf_next = bf->bf_next;
@@ -323,8 +329,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
323 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { 329 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
324 /* transmit completion, subframe is 330 /* transmit completion, subframe is
325 * acked by block ack */ 331 * acked by block ack */
332 acked_cnt++;
326 } else if (!isaggr && txok) { 333 } else if (!isaggr && txok) {
327 /* transmit completion */ 334 /* transmit completion */
335 acked_cnt++;
328 } else { 336 } else {
329 if (!(tid->state & AGGR_CLEANUP) && 337 if (!(tid->state & AGGR_CLEANUP) &&
330 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 338 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
@@ -335,6 +343,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
335 bf->bf_state.bf_type |= BUF_XRETRY; 343 bf->bf_state.bf_type |= BUF_XRETRY;
336 txfail = 1; 344 txfail = 1;
337 sendbar = 1; 345 sendbar = 1;
346 txfail_cnt++;
338 } 347 }
339 } else { 348 } else {
340 /* 349 /*
@@ -361,6 +370,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
361 ath_tx_update_baw(sc, tid, bf->bf_seqno); 370 ath_tx_update_baw(sc, tid, bf->bf_seqno);
362 spin_unlock_bh(&txq->axq_lock); 371 spin_unlock_bh(&txq->axq_lock);
363 372
373 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
374 ath_tx_rc_status(bf, ds, nbad, txok, true);
375 rc_update = false;
376 } else {
377 ath_tx_rc_status(bf, ds, nbad, txok, false);
378 }
379
364 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); 380 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
365 } else { 381 } else {
366 /* retry the un-acked ones */ 382 /* retry the un-acked ones */
@@ -1734,7 +1750,7 @@ exit:
1734/*****************/ 1750/*****************/
1735 1751
1736static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 1752static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1737 struct ath_xmit_status *tx_status) 1753 int tx_flags)
1738{ 1754{
1739 struct ieee80211_hw *hw = sc->hw; 1755 struct ieee80211_hw *hw = sc->hw;
1740 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1756 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1755,18 +1771,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1755 tx_info->rate_driver_data[0] = NULL; 1771 tx_info->rate_driver_data[0] = NULL;
1756 } 1772 }
1757 1773
1758 if (tx_status->flags & ATH_TX_BAR) { 1774 if (tx_flags & ATH_TX_BAR)
1759 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1775 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1760 tx_status->flags &= ~ATH_TX_BAR;
1761 }
1762 1776
1763 if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { 1777 if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
1764 /* Frame was ACKed */ 1778 /* Frame was ACKed */
1765 tx_info->flags |= IEEE80211_TX_STAT_ACK; 1779 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1766 } 1780 }
1767 1781
1768 tx_info->status.rates[0].count = tx_status->retries + 1;
1769
1770 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1782 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1771 padsize = hdrlen & 3; 1783 padsize = hdrlen & 3;
1772 if (padsize && hdrlen >= 24) { 1784 if (padsize && hdrlen >= 24) {
@@ -1789,29 +1801,22 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1789 int txok, int sendbar) 1801 int txok, int sendbar)
1790{ 1802{
1791 struct sk_buff *skb = bf->bf_mpdu; 1803 struct sk_buff *skb = bf->bf_mpdu;
1792 struct ath_xmit_status tx_status;
1793 unsigned long flags; 1804 unsigned long flags;
1805 int tx_flags = 0;
1794 1806
1795 /*
1796 * Set retry information.
1797 * NB: Don't use the information in the descriptor, because the frame
1798 * could be software retried.
1799 */
1800 tx_status.retries = bf->bf_retries;
1801 tx_status.flags = 0;
1802 1807
1803 if (sendbar) 1808 if (sendbar)
1804 tx_status.flags = ATH_TX_BAR; 1809 tx_flags = ATH_TX_BAR;
1805 1810
1806 if (!txok) { 1811 if (!txok) {
1807 tx_status.flags |= ATH_TX_ERROR; 1812 tx_flags |= ATH_TX_ERROR;
1808 1813
1809 if (bf_isxretried(bf)) 1814 if (bf_isxretried(bf))
1810 tx_status.flags |= ATH_TX_XRETRY; 1815 tx_flags |= ATH_TX_XRETRY;
1811 } 1816 }
1812 1817
1813 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1818 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1814 ath_tx_complete(sc, skb, &tx_status); 1819 ath_tx_complete(sc, skb, tx_flags);
1815 1820
1816 /* 1821 /*
1817 * Return the list of ath_buf of this mpdu to free queue 1822 * Return the list of ath_buf of this mpdu to free queue
@@ -1852,27 +1857,40 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1852 return nbad; 1857 return nbad;
1853} 1858}
1854 1859
1855static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad) 1860static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1861 int nbad, int txok, bool update_rc)
1856{ 1862{
1857 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 1863 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
1858 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1864 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1859 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1865 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1860 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 1866 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1867 struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
1868 u8 i, tx_rateindex;
1869
1870 if (txok)
1871 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
1861 1872
1862 tx_info_priv->update_rc = false; 1873 tx_rateindex = ds->ds_txstat.ts_rateindex;
1874 WARN_ON(tx_rateindex >= hw->max_rates);
1875
1876 tx_info_priv->update_rc = update_rc;
1863 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) 1877 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1864 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 1878 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1865 1879
1866 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 1880 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1867 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { 1881 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1868 if (ieee80211_is_data(hdr->frame_control)) { 1882 if (ieee80211_is_data(hdr->frame_control)) {
1869 memcpy(&tx_info_priv->tx, &ds->ds_txstat, 1883 memcpy(&tx_info_priv->tx, &ds->ds_txstat,
1870 sizeof(tx_info_priv->tx)); 1884 sizeof(tx_info_priv->tx));
1871 tx_info_priv->n_frames = bf->bf_nframes; 1885 tx_info_priv->n_frames = bf->bf_nframes;
1872 tx_info_priv->n_bad_frames = nbad; 1886 tx_info_priv->n_bad_frames = nbad;
1873 tx_info_priv->update_rc = true;
1874 } 1887 }
1875 } 1888 }
1889
1890 for (i = tx_rateindex + 1; i < hw->max_rates; i++)
1891 tx_info->status.rates[i].count = 0;
1892
1893 tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
1876} 1894}
1877 1895
1878static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) 1896static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
@@ -1897,7 +1915,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1897 struct ath_buf *bf, *lastbf, *bf_held = NULL; 1915 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1898 struct list_head bf_head; 1916 struct list_head bf_head;
1899 struct ath_desc *ds; 1917 struct ath_desc *ds;
1900 int txok, nbad = 0; 1918 int txok;
1901 int status; 1919 int status;
1902 1920
1903 DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", 1921 DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
@@ -1991,13 +2009,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1991 bf->bf_retries = ds->ds_txstat.ts_longretry; 2009 bf->bf_retries = ds->ds_txstat.ts_longretry;
1992 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 2010 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
1993 bf->bf_state.bf_type |= BUF_XRETRY; 2011 bf->bf_state.bf_type |= BUF_XRETRY;
1994 nbad = 0; 2012 ath_tx_rc_status(bf, ds, 0, txok, true);
1995 } else {
1996 nbad = ath_tx_num_badfrms(sc, bf, txok);
1997 } 2013 }
1998 2014
1999 ath_tx_rc_status(bf, ds, nbad);
2000
2001 if (bf_isampdu(bf)) 2015 if (bf_isampdu(bf))
2002 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2016 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
2003 else 2017 else