diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 83 |
1 files changed, 32 insertions, 51 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 86b54ddd01c..745d91995d7 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -251,6 +251,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
251 | 251 | ||
252 | ATH_TXBUF_RESET(tbf); | 252 | ATH_TXBUF_RESET(tbf); |
253 | 253 | ||
254 | tbf->aphy = bf->aphy; | ||
254 | tbf->bf_mpdu = bf->bf_mpdu; | 255 | tbf->bf_mpdu = bf->bf_mpdu; |
255 | tbf->bf_buf_addr = bf->bf_buf_addr; | 256 | tbf->bf_buf_addr = bf->bf_buf_addr; |
256 | *(tbf->bf_desc) = *(bf->bf_desc); | 257 | *(tbf->bf_desc) = *(bf->bf_desc); |
@@ -270,7 +271,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
270 | struct ieee80211_hw *hw; | 271 | struct ieee80211_hw *hw; |
271 | struct ieee80211_hdr *hdr; | 272 | struct ieee80211_hdr *hdr; |
272 | struct ieee80211_tx_info *tx_info; | 273 | struct ieee80211_tx_info *tx_info; |
273 | struct ath_tx_info_priv *tx_info_priv; | ||
274 | struct ath_atx_tid *tid = NULL; | 274 | struct ath_atx_tid *tid = NULL; |
275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
276 | struct ath_desc *ds = bf_last->bf_desc; | 276 | struct ath_desc *ds = bf_last->bf_desc; |
@@ -284,8 +284,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
284 | hdr = (struct ieee80211_hdr *)skb->data; | 284 | hdr = (struct ieee80211_hdr *)skb->data; |
285 | 285 | ||
286 | tx_info = IEEE80211_SKB_CB(skb); | 286 | tx_info = IEEE80211_SKB_CB(skb); |
287 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0]; | 287 | hw = bf->aphy->hw; |
288 | hw = tx_info_priv->aphy->hw; | ||
289 | 288 | ||
290 | rcu_read_lock(); | 289 | rcu_read_lock(); |
291 | 290 | ||
@@ -464,7 +463,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
464 | struct sk_buff *skb; | 463 | struct sk_buff *skb; |
465 | struct ieee80211_tx_info *tx_info; | 464 | struct ieee80211_tx_info *tx_info; |
466 | struct ieee80211_tx_rate *rates; | 465 | struct ieee80211_tx_rate *rates; |
467 | struct ath_tx_info_priv *tx_info_priv; | ||
468 | u32 max_4ms_framelen, frmlen; | 466 | u32 max_4ms_framelen, frmlen; |
469 | u16 aggr_limit, legacy = 0; | 467 | u16 aggr_limit, legacy = 0; |
470 | int i; | 468 | int i; |
@@ -472,7 +470,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
472 | skb = bf->bf_mpdu; | 470 | skb = bf->bf_mpdu; |
473 | tx_info = IEEE80211_SKB_CB(skb); | 471 | tx_info = IEEE80211_SKB_CB(skb); |
474 | rates = tx_info->control.rates; | 472 | rates = tx_info->control.rates; |
475 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
476 | 473 | ||
477 | /* | 474 | /* |
478 | * Find the lowest frame length among the rate series that will have a | 475 | * Find the lowest frame length among the rate series that will have a |
@@ -702,7 +699,6 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
702 | /* anchor last desc of aggregate */ | 699 | /* anchor last desc of aggregate */ |
703 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | 700 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); |
704 | 701 | ||
705 | txq->axq_aggr_depth++; | ||
706 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 702 | ath_tx_txqaddbuf(sc, txq, &bf_q); |
707 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 703 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
708 | 704 | ||
@@ -878,8 +874,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
878 | INIT_LIST_HEAD(&txq->axq_acq); | 874 | INIT_LIST_HEAD(&txq->axq_acq); |
879 | spin_lock_init(&txq->axq_lock); | 875 | spin_lock_init(&txq->axq_lock); |
880 | txq->axq_depth = 0; | 876 | txq->axq_depth = 0; |
881 | txq->axq_aggr_depth = 0; | ||
882 | txq->axq_linkbuf = NULL; | ||
883 | txq->axq_tx_inprogress = false; | 877 | txq->axq_tx_inprogress = false; |
884 | sc->tx.txqsetup |= 1<<qnum; | 878 | sc->tx.txqsetup |= 1<<qnum; |
885 | } | 879 | } |
@@ -1014,7 +1008,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1014 | 1008 | ||
1015 | if (list_empty(&txq->axq_q)) { | 1009 | if (list_empty(&txq->axq_q)) { |
1016 | txq->axq_link = NULL; | 1010 | txq->axq_link = NULL; |
1017 | txq->axq_linkbuf = NULL; | ||
1018 | spin_unlock_bh(&txq->axq_lock); | 1011 | spin_unlock_bh(&txq->axq_lock); |
1019 | break; | 1012 | break; |
1020 | } | 1013 | } |
@@ -1199,7 +1192,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1199 | 1192 | ||
1200 | list_splice_tail_init(head, &txq->axq_q); | 1193 | list_splice_tail_init(head, &txq->axq_q); |
1201 | txq->axq_depth++; | 1194 | txq->axq_depth++; |
1202 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | ||
1203 | 1195 | ||
1204 | ath_print(common, ATH_DBG_QUEUE, | 1196 | ath_print(common, ATH_DBG_QUEUE, |
1205 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | 1197 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); |
@@ -1560,21 +1552,26 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1560 | struct ath_softc *sc = aphy->sc; | 1552 | struct ath_softc *sc = aphy->sc; |
1561 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1553 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1562 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1554 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1563 | struct ath_tx_info_priv *tx_info_priv; | ||
1564 | int hdrlen; | 1555 | int hdrlen; |
1565 | __le16 fc; | 1556 | __le16 fc; |
1566 | 1557 | ||
1567 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | 1558 | tx_info->pad[0] = 0; |
1568 | if (unlikely(!tx_info_priv)) | 1559 | switch (txctl->frame_type) { |
1569 | return -ENOMEM; | 1560 | case ATH9K_NOT_INTERNAL: |
1570 | tx_info->rate_driver_data[0] = tx_info_priv; | 1561 | break; |
1571 | tx_info_priv->aphy = aphy; | 1562 | case ATH9K_INT_PAUSE: |
1572 | tx_info_priv->frame_type = txctl->frame_type; | 1563 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; |
1564 | /* fall through */ | ||
1565 | case ATH9K_INT_UNPAUSE: | ||
1566 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; | ||
1567 | break; | ||
1568 | } | ||
1573 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1569 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1574 | fc = hdr->frame_control; | 1570 | fc = hdr->frame_control; |
1575 | 1571 | ||
1576 | ATH_TXBUF_RESET(bf); | 1572 | ATH_TXBUF_RESET(bf); |
1577 | 1573 | ||
1574 | bf->aphy = aphy; | ||
1578 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | 1575 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); |
1579 | 1576 | ||
1580 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) | 1577 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) |
@@ -1599,8 +1596,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1599 | skb->len, DMA_TO_DEVICE); | 1596 | skb->len, DMA_TO_DEVICE); |
1600 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { | 1597 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { |
1601 | bf->bf_mpdu = NULL; | 1598 | bf->bf_mpdu = NULL; |
1602 | kfree(tx_info_priv); | ||
1603 | tx_info->rate_driver_data[0] = NULL; | ||
1604 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 1599 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1605 | "dma_mapping_error() on TX\n"); | 1600 | "dma_mapping_error() on TX\n"); |
1606 | return -ENOMEM; | 1601 | return -ENOMEM; |
@@ -1781,27 +1776,17 @@ exit: | |||
1781 | /*****************/ | 1776 | /*****************/ |
1782 | 1777 | ||
1783 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1778 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1784 | int tx_flags) | 1779 | struct ath_wiphy *aphy, int tx_flags) |
1785 | { | 1780 | { |
1786 | struct ieee80211_hw *hw = sc->hw; | 1781 | struct ieee80211_hw *hw = sc->hw; |
1787 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1782 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1788 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1789 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1783 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1790 | int hdrlen, padsize; | 1784 | int hdrlen, padsize; |
1791 | int frame_type = ATH9K_NOT_INTERNAL; | ||
1792 | 1785 | ||
1793 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1786 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1794 | 1787 | ||
1795 | if (tx_info_priv) { | 1788 | if (aphy) |
1796 | hw = tx_info_priv->aphy->hw; | 1789 | hw = aphy->hw; |
1797 | frame_type = tx_info_priv->frame_type; | ||
1798 | } | ||
1799 | |||
1800 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
1801 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
1802 | kfree(tx_info_priv); | ||
1803 | tx_info->rate_driver_data[0] = NULL; | ||
1804 | } | ||
1805 | 1790 | ||
1806 | if (tx_flags & ATH_TX_BAR) | 1791 | if (tx_flags & ATH_TX_BAR) |
1807 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1792 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
@@ -1833,10 +1818,10 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1833 | SC_OP_WAIT_FOR_TX_ACK)); | 1818 | SC_OP_WAIT_FOR_TX_ACK)); |
1834 | } | 1819 | } |
1835 | 1820 | ||
1836 | if (frame_type == ATH9K_NOT_INTERNAL) | 1821 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
1837 | ieee80211_tx_status(hw, skb); | ||
1838 | else | ||
1839 | ath9k_tx_status(hw, skb); | 1822 | ath9k_tx_status(hw, skb); |
1823 | else | ||
1824 | ieee80211_tx_status(hw, skb); | ||
1840 | } | 1825 | } |
1841 | 1826 | ||
1842 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1827 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1859,7 +1844,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1859 | } | 1844 | } |
1860 | 1845 | ||
1861 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1846 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1862 | ath_tx_complete(sc, skb, tx_flags); | 1847 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); |
1863 | ath_debug_stat_tx(sc, txq, bf); | 1848 | ath_debug_stat_tx(sc, txq, bf); |
1864 | 1849 | ||
1865 | /* | 1850 | /* |
@@ -1907,8 +1892,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1907 | struct sk_buff *skb = bf->bf_mpdu; | 1892 | struct sk_buff *skb = bf->bf_mpdu; |
1908 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1893 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1909 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1894 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1910 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1895 | struct ieee80211_hw *hw = bf->aphy->hw; |
1911 | struct ieee80211_hw *hw = tx_info_priv->aphy->hw; | ||
1912 | u8 i, tx_rateindex; | 1896 | u8 i, tx_rateindex; |
1913 | 1897 | ||
1914 | if (txok) | 1898 | if (txok) |
@@ -1917,17 +1901,22 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1917 | tx_rateindex = ds->ds_txstat.ts_rateindex; | 1901 | tx_rateindex = ds->ds_txstat.ts_rateindex; |
1918 | WARN_ON(tx_rateindex >= hw->max_rates); | 1902 | WARN_ON(tx_rateindex >= hw->max_rates); |
1919 | 1903 | ||
1920 | tx_info_priv->update_rc = update_rc; | 1904 | if (update_rc) |
1905 | tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC; | ||
1921 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1906 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1922 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1907 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1923 | 1908 | ||
1924 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1909 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
1925 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 1910 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
1926 | if (ieee80211_is_data(hdr->frame_control)) { | 1911 | if (ieee80211_is_data(hdr->frame_control)) { |
1927 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | 1912 | if (ds->ds_txstat.ts_flags & |
1928 | sizeof(tx_info_priv->tx)); | 1913 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) |
1929 | tx_info_priv->n_frames = bf->bf_nframes; | 1914 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; |
1930 | tx_info_priv->n_bad_frames = nbad; | 1915 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || |
1916 | (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) | ||
1917 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | ||
1918 | tx_info->status.ampdu_len = bf->bf_nframes; | ||
1919 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | ||
1931 | } | 1920 | } |
1932 | } | 1921 | } |
1933 | 1922 | ||
@@ -1971,7 +1960,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
1971 | spin_lock_bh(&txq->axq_lock); | 1960 | spin_lock_bh(&txq->axq_lock); |
1972 | if (list_empty(&txq->axq_q)) { | 1961 | if (list_empty(&txq->axq_q)) { |
1973 | txq->axq_link = NULL; | 1962 | txq->axq_link = NULL; |
1974 | txq->axq_linkbuf = NULL; | ||
1975 | spin_unlock_bh(&txq->axq_lock); | 1963 | spin_unlock_bh(&txq->axq_lock); |
1976 | break; | 1964 | break; |
1977 | } | 1965 | } |
@@ -2005,10 +1993,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2005 | spin_unlock_bh(&txq->axq_lock); | 1993 | spin_unlock_bh(&txq->axq_lock); |
2006 | break; | 1994 | break; |
2007 | } | 1995 | } |
2008 | if (bf->bf_desc == txq->axq_lastdsWithCTS) | ||
2009 | txq->axq_lastdsWithCTS = NULL; | ||
2010 | if (ds == txq->axq_gatingds) | ||
2011 | txq->axq_gatingds = NULL; | ||
2012 | 1996 | ||
2013 | /* | 1997 | /* |
2014 | * Remove ath_buf's of the same transmit unit from txq, | 1998 | * Remove ath_buf's of the same transmit unit from txq, |
@@ -2022,9 +2006,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2022 | &txq->axq_q, lastbf->list.prev); | 2006 | &txq->axq_q, lastbf->list.prev); |
2023 | 2007 | ||
2024 | txq->axq_depth--; | 2008 | txq->axq_depth--; |
2025 | if (bf_isaggr(bf)) | ||
2026 | txq->axq_aggr_depth--; | ||
2027 | |||
2028 | txok = (ds->ds_txstat.ts_status == 0); | 2009 | txok = (ds->ds_txstat.ts_status == 0); |
2029 | txq->axq_tx_inprogress = false; | 2010 | txq->axq_tx_inprogress = false; |
2030 | spin_unlock_bh(&txq->axq_lock); | 2011 | spin_unlock_bh(&txq->axq_lock); |