diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-08-27 18:32:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-30 15:38:53 -0400 |
commit | fa05f87ad4213a3e99bea6f5e73611dc27b4304a (patch) | |
tree | 840ec63807e12f039c58b505e0f9991ab1689b96 /drivers/net/wireless/ath | |
parent | 6a0ddaef7c2f50f2d3ee8dfbf37f66dda11f061a (diff) |
ath9k: move seqno allocation in the tx path to ath_tx_setup_buffer
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e3eeca98fbba..bd523619e7b7 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1717,17 +1717,19 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
1717 | 1717 | ||
1718 | } | 1718 | } |
1719 | 1719 | ||
1720 | static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | 1720 | static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, |
1721 | struct ath_txq *txq, | 1721 | struct ath_txq *txq, |
1722 | struct ath_atx_tid *tid, | ||
1722 | struct sk_buff *skb) | 1723 | struct sk_buff *skb) |
1723 | { | 1724 | { |
1724 | struct ath_softc *sc = hw->priv; | ||
1725 | struct ath_hw *ah = sc->sc_ah; | 1725 | struct ath_hw *ah = sc->sc_ah; |
1726 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1726 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1727 | struct ath_frame_info *fi = get_frame_info(skb); | 1727 | struct ath_frame_info *fi = get_frame_info(skb); |
1728 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1728 | struct ath_buf *bf; | 1729 | struct ath_buf *bf; |
1729 | struct ath_desc *ds; | 1730 | struct ath_desc *ds; |
1730 | int frm_type; | 1731 | int frm_type; |
1732 | u16 seqno; | ||
1731 | 1733 | ||
1732 | bf = ath_tx_get_buffer(sc); | 1734 | bf = ath_tx_get_buffer(sc); |
1733 | if (!bf) { | 1735 | if (!bf) { |
@@ -1737,6 +1739,13 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1737 | 1739 | ||
1738 | ATH_TXBUF_RESET(bf); | 1740 | ATH_TXBUF_RESET(bf); |
1739 | 1741 | ||
1742 | if (tid) { | ||
1743 | seqno = tid->seq_next; | ||
1744 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | ||
1745 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1746 | bf->bf_state.seqno = seqno; | ||
1747 | } | ||
1748 | |||
1740 | bf->bf_flags = setup_tx_flags(skb); | 1749 | bf->bf_flags = setup_tx_flags(skb); |
1741 | bf->bf_mpdu = skb; | 1750 | bf->bf_mpdu = skb; |
1742 | 1751 | ||
@@ -1773,15 +1782,15 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1773 | } | 1782 | } |
1774 | 1783 | ||
1775 | /* FIXME: tx power */ | 1784 | /* FIXME: tx power */ |
1776 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | 1785 | static int ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, |
1777 | struct ath_tx_control *txctl) | 1786 | struct ath_tx_control *txctl) |
1778 | { | 1787 | { |
1779 | struct sk_buff *skb = bf->bf_mpdu; | ||
1780 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1788 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1781 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1789 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1782 | struct list_head bf_head; | 1790 | struct list_head bf_head; |
1783 | struct ath_atx_tid *tid = NULL; | 1791 | struct ath_atx_tid *tid = NULL; |
1784 | u16 seqno; | 1792 | struct ath_buf *bf; |
1793 | int ret = 0; | ||
1785 | u8 tidno; | 1794 | u8 tidno; |
1786 | 1795 | ||
1787 | spin_lock_bh(&txctl->txq->axq_lock); | 1796 | spin_lock_bh(&txctl->txq->axq_lock); |
@@ -1791,15 +1800,15 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1791 | IEEE80211_QOS_CTL_TID_MASK; | 1800 | IEEE80211_QOS_CTL_TID_MASK; |
1792 | tid = ATH_AN_2_TID(txctl->an, tidno); | 1801 | tid = ATH_AN_2_TID(txctl->an, tidno); |
1793 | 1802 | ||
1794 | seqno = tid->seq_next; | ||
1795 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | ||
1796 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1797 | |||
1798 | bf->bf_state.seqno = seqno; | ||
1799 | |||
1800 | WARN_ON(tid->ac->txq != txctl->txq); | 1803 | WARN_ON(tid->ac->txq != txctl->txq); |
1801 | } | 1804 | } |
1802 | 1805 | ||
1806 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); | ||
1807 | if (unlikely(!bf)) { | ||
1808 | ret = -ENOMEM; | ||
1809 | goto out; | ||
1810 | } | ||
1811 | |||
1803 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { | 1812 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { |
1804 | /* | 1813 | /* |
1805 | * Try aggregation if it's a unicast data frame | 1814 | * Try aggregation if it's a unicast data frame |
@@ -1825,7 +1834,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1825 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); | 1834 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); |
1826 | } | 1835 | } |
1827 | 1836 | ||
1837 | out: | ||
1828 | spin_unlock_bh(&txctl->txq->axq_lock); | 1838 | spin_unlock_bh(&txctl->txq->axq_lock); |
1839 | return ret; | ||
1829 | } | 1840 | } |
1830 | 1841 | ||
1831 | /* Upon failure caller should free skb */ | 1842 | /* Upon failure caller should free skb */ |
@@ -1838,7 +1849,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1838 | struct ieee80211_vif *vif = info->control.vif; | 1849 | struct ieee80211_vif *vif = info->control.vif; |
1839 | struct ath_softc *sc = hw->priv; | 1850 | struct ath_softc *sc = hw->priv; |
1840 | struct ath_txq *txq = txctl->txq; | 1851 | struct ath_txq *txq = txctl->txq; |
1841 | struct ath_buf *bf; | ||
1842 | int padpos, padsize; | 1852 | int padpos, padsize; |
1843 | int frmlen = skb->len + FCS_LEN; | 1853 | int frmlen = skb->len + FCS_LEN; |
1844 | int q; | 1854 | int q; |
@@ -1885,10 +1895,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1885 | * info are no longer valid (overwritten by the ath_frame_info data. | 1895 | * info are no longer valid (overwritten by the ath_frame_info data. |
1886 | */ | 1896 | */ |
1887 | 1897 | ||
1888 | bf = ath_tx_setup_buffer(hw, txctl->txq, skb); | ||
1889 | if (unlikely(!bf)) | ||
1890 | return -ENOMEM; | ||
1891 | |||
1892 | q = skb_get_queue_mapping(skb); | 1898 | q = skb_get_queue_mapping(skb); |
1893 | spin_lock_bh(&txq->axq_lock); | 1899 | spin_lock_bh(&txq->axq_lock); |
1894 | if (txq == sc->tx.txq_map[q] && | 1900 | if (txq == sc->tx.txq_map[q] && |
@@ -1898,9 +1904,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1898 | } | 1904 | } |
1899 | spin_unlock_bh(&txq->axq_lock); | 1905 | spin_unlock_bh(&txq->axq_lock); |
1900 | 1906 | ||
1901 | ath_tx_start_dma(sc, bf, txctl); | 1907 | return ath_tx_start_dma(sc, skb, txctl); |
1902 | |||
1903 | return 0; | ||
1904 | } | 1908 | } |
1905 | 1909 | ||
1906 | /*****************/ | 1910 | /*****************/ |