diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 136 |
1 files changed, 71 insertions, 65 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index dcac811ddab5..68a1c7612e9b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -55,8 +55,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
55 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 55 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
56 | struct list_head *head); | 56 | struct list_head *head); |
57 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); | 57 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); |
58 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | 58 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, |
59 | int nframes, int nbad, int txok, bool update_rc); | 59 | struct ath_tx_status *ts, int nframes, int nbad, |
60 | int txok, bool update_rc); | ||
60 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 61 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
61 | int seqno); | 62 | int seqno); |
62 | 63 | ||
@@ -295,7 +296,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
295 | 296 | ||
296 | ATH_TXBUF_RESET(tbf); | 297 | ATH_TXBUF_RESET(tbf); |
297 | 298 | ||
298 | tbf->aphy = bf->aphy; | ||
299 | tbf->bf_mpdu = bf->bf_mpdu; | 299 | tbf->bf_mpdu = bf->bf_mpdu; |
300 | tbf->bf_buf_addr = bf->bf_buf_addr; | 300 | tbf->bf_buf_addr = bf->bf_buf_addr; |
301 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); | 301 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); |
@@ -343,7 +343,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
343 | struct ath_node *an = NULL; | 343 | struct ath_node *an = NULL; |
344 | struct sk_buff *skb; | 344 | struct sk_buff *skb; |
345 | struct ieee80211_sta *sta; | 345 | struct ieee80211_sta *sta; |
346 | struct ieee80211_hw *hw; | 346 | struct ieee80211_hw *hw = sc->hw; |
347 | struct ieee80211_hdr *hdr; | 347 | struct ieee80211_hdr *hdr; |
348 | struct ieee80211_tx_info *tx_info; | 348 | struct ieee80211_tx_info *tx_info; |
349 | struct ath_atx_tid *tid = NULL; | 349 | struct ath_atx_tid *tid = NULL; |
@@ -362,7 +362,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
362 | hdr = (struct ieee80211_hdr *)skb->data; | 362 | hdr = (struct ieee80211_hdr *)skb->data; |
363 | 363 | ||
364 | tx_info = IEEE80211_SKB_CB(skb); | 364 | tx_info = IEEE80211_SKB_CB(skb); |
365 | hw = bf->aphy->hw; | ||
366 | 365 | ||
367 | memcpy(rates, tx_info->control.rates, sizeof(rates)); | 366 | memcpy(rates, tx_info->control.rates, sizeof(rates)); |
368 | 367 | ||
@@ -381,7 +380,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
381 | !bf->bf_stale || bf_next != NULL) | 380 | !bf->bf_stale || bf_next != NULL) |
382 | list_move_tail(&bf->list, &bf_head); | 381 | list_move_tail(&bf->list, &bf_head); |
383 | 382 | ||
384 | ath_tx_rc_status(bf, ts, 1, 1, 0, false); | 383 | ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); |
385 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 384 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
386 | 0, 0); | 385 | 0, 0); |
387 | 386 | ||
@@ -487,10 +486,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
487 | 486 | ||
488 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 487 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
489 | memcpy(tx_info->control.rates, rates, sizeof(rates)); | 488 | memcpy(tx_info->control.rates, rates, sizeof(rates)); |
490 | ath_tx_rc_status(bf, ts, nframes, nbad, txok, true); | 489 | ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, true); |
491 | rc_update = false; | 490 | rc_update = false; |
492 | } else { | 491 | } else { |
493 | ath_tx_rc_status(bf, ts, nframes, nbad, txok, false); | 492 | ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, false); |
494 | } | 493 | } |
495 | 494 | ||
496 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 495 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
@@ -514,7 +513,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
514 | 513 | ||
515 | bf->bf_state.bf_type |= | 514 | bf->bf_state.bf_type |= |
516 | BUF_XRETRY; | 515 | BUF_XRETRY; |
517 | ath_tx_rc_status(bf, ts, nframes, | 516 | ath_tx_rc_status(sc, bf, ts, nframes, |
518 | nbad, 0, false); | 517 | nbad, 0, false); |
519 | ath_tx_complete_buf(sc, bf, txq, | 518 | ath_tx_complete_buf(sc, bf, txq, |
520 | &bf_head, | 519 | &bf_head, |
@@ -564,8 +563,11 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
564 | 563 | ||
565 | rcu_read_unlock(); | 564 | rcu_read_unlock(); |
566 | 565 | ||
567 | if (needreset) | 566 | if (needreset) { |
567 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
568 | ath_reset(sc, false); | 568 | ath_reset(sc, false); |
569 | spin_lock_bh(&sc->sc_pcu_lock); | ||
570 | } | ||
569 | } | 571 | } |
570 | 572 | ||
571 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | 573 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1207,8 +1209,17 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1207 | ath_err(common, "Failed to stop TX DMA!\n"); | 1209 | ath_err(common, "Failed to stop TX DMA!\n"); |
1208 | 1210 | ||
1209 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1211 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
1210 | if (ATH_TXQ_SETUP(sc, i)) | 1212 | if (!ATH_TXQ_SETUP(sc, i)) |
1211 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | 1213 | continue; |
1214 | |||
1215 | /* | ||
1216 | * The caller will resume queues with ieee80211_wake_queues. | ||
1217 | * Mark the queue as not stopped to prevent ath_tx_complete | ||
1218 | * from waking the queue too early. | ||
1219 | */ | ||
1220 | txq = &sc->tx.txq[i]; | ||
1221 | txq->stopped = false; | ||
1222 | ath_draintxq(sc, txq, retry_tx); | ||
1212 | } | 1223 | } |
1213 | 1224 | ||
1214 | return !npend; | 1225 | return !npend; |
@@ -1435,8 +1446,7 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1435 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | 1446 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, |
1436 | int framelen) | 1447 | int framelen) |
1437 | { | 1448 | { |
1438 | struct ath_wiphy *aphy = hw->priv; | 1449 | struct ath_softc *sc = hw->priv; |
1439 | struct ath_softc *sc = aphy->sc; | ||
1440 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1450 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1441 | struct ieee80211_sta *sta = tx_info->control.sta; | 1451 | struct ieee80211_sta *sta = tx_info->control.sta; |
1442 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 1452 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
@@ -1654,8 +1664,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1654 | struct ath_txq *txq, | 1664 | struct ath_txq *txq, |
1655 | struct sk_buff *skb) | 1665 | struct sk_buff *skb) |
1656 | { | 1666 | { |
1657 | struct ath_wiphy *aphy = hw->priv; | 1667 | struct ath_softc *sc = hw->priv; |
1658 | struct ath_softc *sc = aphy->sc; | ||
1659 | struct ath_hw *ah = sc->sc_ah; | 1668 | struct ath_hw *ah = sc->sc_ah; |
1660 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1669 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1661 | struct ath_frame_info *fi = get_frame_info(skb); | 1670 | struct ath_frame_info *fi = get_frame_info(skb); |
@@ -1671,7 +1680,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1671 | 1680 | ||
1672 | ATH_TXBUF_RESET(bf); | 1681 | ATH_TXBUF_RESET(bf); |
1673 | 1682 | ||
1674 | bf->aphy = aphy; | ||
1675 | bf->bf_flags = setup_tx_flags(skb); | 1683 | bf->bf_flags = setup_tx_flags(skb); |
1676 | bf->bf_mpdu = skb; | 1684 | bf->bf_mpdu = skb; |
1677 | 1685 | ||
@@ -1757,8 +1765,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1757 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1765 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1758 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1766 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1759 | struct ieee80211_sta *sta = info->control.sta; | 1767 | struct ieee80211_sta *sta = info->control.sta; |
1760 | struct ath_wiphy *aphy = hw->priv; | 1768 | struct ath_softc *sc = hw->priv; |
1761 | struct ath_softc *sc = aphy->sc; | ||
1762 | struct ath_txq *txq = txctl->txq; | 1769 | struct ath_txq *txq = txctl->txq; |
1763 | struct ath_buf *bf; | 1770 | struct ath_buf *bf; |
1764 | int padpos, padsize; | 1771 | int padpos, padsize; |
@@ -1810,7 +1817,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1810 | spin_lock_bh(&txq->axq_lock); | 1817 | spin_lock_bh(&txq->axq_lock); |
1811 | if (txq == sc->tx.txq_map[q] && | 1818 | if (txq == sc->tx.txq_map[q] && |
1812 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { | 1819 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { |
1813 | ath_mac80211_stop_queue(sc, q); | 1820 | ieee80211_stop_queue(sc->hw, q); |
1814 | txq->stopped = 1; | 1821 | txq->stopped = 1; |
1815 | } | 1822 | } |
1816 | spin_unlock_bh(&txq->axq_lock); | 1823 | spin_unlock_bh(&txq->axq_lock); |
@@ -1825,8 +1832,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1825 | /*****************/ | 1832 | /*****************/ |
1826 | 1833 | ||
1827 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1834 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1828 | struct ath_wiphy *aphy, int tx_flags, int ftype, | 1835 | int tx_flags, int ftype, struct ath_txq *txq) |
1829 | struct ath_txq *txq) | ||
1830 | { | 1836 | { |
1831 | struct ieee80211_hw *hw = sc->hw; | 1837 | struct ieee80211_hw *hw = sc->hw; |
1832 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1838 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
@@ -1836,9 +1842,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1836 | 1842 | ||
1837 | ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1843 | ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1838 | 1844 | ||
1839 | if (aphy) | ||
1840 | hw = aphy->hw; | ||
1841 | |||
1842 | if (tx_flags & ATH_TX_BAR) | 1845 | if (tx_flags & ATH_TX_BAR) |
1843 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1846 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1844 | 1847 | ||
@@ -1868,19 +1871,20 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1868 | PS_WAIT_FOR_TX_ACK)); | 1871 | PS_WAIT_FOR_TX_ACK)); |
1869 | } | 1872 | } |
1870 | 1873 | ||
1871 | if (unlikely(ftype)) | 1874 | q = skb_get_queue_mapping(skb); |
1872 | ath9k_tx_status(hw, skb, ftype); | 1875 | if (txq == sc->tx.txq_map[q]) { |
1873 | else { | 1876 | spin_lock_bh(&txq->axq_lock); |
1874 | q = skb_get_queue_mapping(skb); | 1877 | if (WARN_ON(--txq->pending_frames < 0)) |
1875 | if (txq == sc->tx.txq_map[q]) { | 1878 | txq->pending_frames = 0; |
1876 | spin_lock_bh(&txq->axq_lock); | ||
1877 | if (WARN_ON(--txq->pending_frames < 0)) | ||
1878 | txq->pending_frames = 0; | ||
1879 | spin_unlock_bh(&txq->axq_lock); | ||
1880 | } | ||
1881 | 1879 | ||
1882 | ieee80211_tx_status(hw, skb); | 1880 | if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { |
1881 | ieee80211_wake_queue(sc->hw, q); | ||
1882 | txq->stopped = 0; | ||
1883 | } | ||
1884 | spin_unlock_bh(&txq->axq_lock); | ||
1883 | } | 1885 | } |
1886 | |||
1887 | ieee80211_tx_status(hw, skb); | ||
1884 | } | 1888 | } |
1885 | 1889 | ||
1886 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1890 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1910,8 +1914,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1910 | else | 1914 | else |
1911 | complete(&sc->paprd_complete); | 1915 | complete(&sc->paprd_complete); |
1912 | } else { | 1916 | } else { |
1913 | ath_debug_stat_tx(sc, bf, ts); | 1917 | ath_debug_stat_tx(sc, bf, ts, txq); |
1914 | ath_tx_complete(sc, skb, bf->aphy, tx_flags, | 1918 | ath_tx_complete(sc, skb, tx_flags, |
1915 | bf->bf_state.bfs_ftype, txq); | 1919 | bf->bf_state.bfs_ftype, txq); |
1916 | } | 1920 | } |
1917 | /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't | 1921 | /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't |
@@ -1927,14 +1931,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1927 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | 1931 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); |
1928 | } | 1932 | } |
1929 | 1933 | ||
1930 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | 1934 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, |
1931 | int nframes, int nbad, int txok, bool update_rc) | 1935 | struct ath_tx_status *ts, int nframes, int nbad, |
1936 | int txok, bool update_rc) | ||
1932 | { | 1937 | { |
1933 | struct sk_buff *skb = bf->bf_mpdu; | 1938 | struct sk_buff *skb = bf->bf_mpdu; |
1934 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1939 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1935 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1940 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1936 | struct ieee80211_hw *hw = bf->aphy->hw; | 1941 | struct ieee80211_hw *hw = sc->hw; |
1937 | struct ath_softc *sc = bf->aphy->sc; | ||
1938 | struct ath_hw *ah = sc->sc_ah; | 1942 | struct ath_hw *ah = sc->sc_ah; |
1939 | u8 i, tx_rateindex; | 1943 | u8 i, tx_rateindex; |
1940 | 1944 | ||
@@ -1985,18 +1989,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | |||
1985 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; | 1989 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
1986 | } | 1990 | } |
1987 | 1991 | ||
1988 | /* Has no locking. Must hold spin_lock_bh(&txq->axq_lock) | ||
1989 | * before calling this. | ||
1990 | */ | ||
1991 | static void __ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | ||
1992 | { | ||
1993 | if (txq->mac80211_qnum >= 0 && | ||
1994 | txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { | ||
1995 | if (ath_mac80211_start_queue(sc, txq->mac80211_qnum)) | ||
1996 | txq->stopped = 0; | ||
1997 | } | ||
1998 | } | ||
1999 | |||
2000 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | 1992 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) |
2001 | { | 1993 | { |
2002 | struct ath_hw *ah = sc->sc_ah; | 1994 | struct ath_hw *ah = sc->sc_ah; |
@@ -2007,7 +1999,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2007 | struct ath_tx_status ts; | 1999 | struct ath_tx_status ts; |
2008 | int txok; | 2000 | int txok; |
2009 | int status; | 2001 | int status; |
2010 | int qnum; | ||
2011 | 2002 | ||
2012 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | 2003 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", |
2013 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | 2004 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), |
@@ -2086,11 +2077,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2086 | */ | 2077 | */ |
2087 | if (ts.ts_status & ATH9K_TXERR_XRETRY) | 2078 | if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2088 | bf->bf_state.bf_type |= BUF_XRETRY; | 2079 | bf->bf_state.bf_type |= BUF_XRETRY; |
2089 | ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true); | 2080 | ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true); |
2090 | } | 2081 | } |
2091 | 2082 | ||
2092 | qnum = skb_get_queue_mapping(bf->bf_mpdu); | ||
2093 | |||
2094 | if (bf_isampdu(bf)) | 2083 | if (bf_isampdu(bf)) |
2095 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, | 2084 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, |
2096 | true); | 2085 | true); |
@@ -2098,7 +2087,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2098 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); | 2087 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); |
2099 | 2088 | ||
2100 | spin_lock_bh(&txq->axq_lock); | 2089 | spin_lock_bh(&txq->axq_lock); |
2101 | __ath_wake_mac80211_queue(sc, txq); | ||
2102 | 2090 | ||
2103 | if (sc->sc_flags & SC_OP_TXAGGR) | 2091 | if (sc->sc_flags & SC_OP_TXAGGR) |
2104 | ath_txq_schedule(sc, txq); | 2092 | ath_txq_schedule(sc, txq); |
@@ -2106,6 +2094,28 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2106 | } | 2094 | } |
2107 | } | 2095 | } |
2108 | 2096 | ||
2097 | static void ath_hw_pll_work(struct work_struct *work) | ||
2098 | { | ||
2099 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
2100 | hw_pll_work.work); | ||
2101 | static int count; | ||
2102 | |||
2103 | if (AR_SREV_9485(sc->sc_ah)) { | ||
2104 | if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { | ||
2105 | count++; | ||
2106 | |||
2107 | if (count == 3) { | ||
2108 | /* Rx is hung for more than 500ms. Reset it */ | ||
2109 | ath_reset(sc, true); | ||
2110 | count = 0; | ||
2111 | } | ||
2112 | } else | ||
2113 | count = 0; | ||
2114 | |||
2115 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
2116 | } | ||
2117 | } | ||
2118 | |||
2109 | static void ath_tx_complete_poll_work(struct work_struct *work) | 2119 | static void ath_tx_complete_poll_work(struct work_struct *work) |
2110 | { | 2120 | { |
2111 | struct ath_softc *sc = container_of(work, struct ath_softc, | 2121 | struct ath_softc *sc = container_of(work, struct ath_softc, |
@@ -2154,7 +2164,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
2154 | txq->pending_frames, | 2164 | txq->pending_frames, |
2155 | list_empty(&txq->axq_acq), | 2165 | list_empty(&txq->axq_acq), |
2156 | txq->stopped); | 2166 | txq->stopped); |
2157 | __ath_wake_mac80211_queue(sc, txq); | ||
2158 | ath_txq_schedule(sc, txq); | 2167 | ath_txq_schedule(sc, txq); |
2159 | } | 2168 | } |
2160 | } | 2169 | } |
@@ -2196,7 +2205,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2196 | struct list_head bf_head; | 2205 | struct list_head bf_head; |
2197 | int status; | 2206 | int status; |
2198 | int txok; | 2207 | int txok; |
2199 | int qnum; | ||
2200 | 2208 | ||
2201 | for (;;) { | 2209 | for (;;) { |
2202 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); | 2210 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); |
@@ -2239,11 +2247,9 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2239 | if (!bf_isampdu(bf)) { | 2247 | if (!bf_isampdu(bf)) { |
2240 | if (txs.ts_status & ATH9K_TXERR_XRETRY) | 2248 | if (txs.ts_status & ATH9K_TXERR_XRETRY) |
2241 | bf->bf_state.bf_type |= BUF_XRETRY; | 2249 | bf->bf_state.bf_type |= BUF_XRETRY; |
2242 | ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true); | 2250 | ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true); |
2243 | } | 2251 | } |
2244 | 2252 | ||
2245 | qnum = skb_get_queue_mapping(bf->bf_mpdu); | ||
2246 | |||
2247 | if (bf_isampdu(bf)) | 2253 | if (bf_isampdu(bf)) |
2248 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, | 2254 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, |
2249 | txok, true); | 2255 | txok, true); |
@@ -2252,7 +2258,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2252 | &txs, txok, 0); | 2258 | &txs, txok, 0); |
2253 | 2259 | ||
2254 | spin_lock_bh(&txq->axq_lock); | 2260 | spin_lock_bh(&txq->axq_lock); |
2255 | __ath_wake_mac80211_queue(sc, txq); | ||
2256 | 2261 | ||
2257 | if (!list_empty(&txq->txq_fifo_pending)) { | 2262 | if (!list_empty(&txq->txq_fifo_pending)) { |
2258 | INIT_LIST_HEAD(&bf_head); | 2263 | INIT_LIST_HEAD(&bf_head); |
@@ -2330,6 +2335,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2330 | } | 2335 | } |
2331 | 2336 | ||
2332 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2337 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2338 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
2333 | 2339 | ||
2334 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 2340 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
2335 | error = ath_tx_edma_init(sc); | 2341 | error = ath_tx_edma_init(sc); |