diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2a11cc57ceea..fa12b9060b0b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1108,11 +1108,11 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1108 | if (npend) { | 1108 | if (npend) { |
1109 | int r; | 1109 | int r; |
1110 | 1110 | ||
1111 | ath_print(common, ATH_DBG_XMIT, | 1111 | ath_print(common, ATH_DBG_FATAL, |
1112 | "Unable to stop TxDMA. Reset HAL!\n"); | 1112 | "Unable to stop TxDMA. Reset HAL!\n"); |
1113 | 1113 | ||
1114 | spin_lock_bh(&sc->sc_resetlock); | 1114 | spin_lock_bh(&sc->sc_resetlock); |
1115 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true); | 1115 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); |
1116 | if (r) | 1116 | if (r) |
1117 | ath_print(common, ATH_DBG_FATAL, | 1117 | ath_print(common, ATH_DBG_FATAL, |
1118 | "Unable to reset hardware; reset status %d\n", | 1118 | "Unable to reset hardware; reset status %d\n", |
@@ -1414,17 +1414,9 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, | |||
1414 | * For HT capable stations, we save tidno for later use. | 1414 | * For HT capable stations, we save tidno for later use. |
1415 | * We also override seqno set by upper layer with the one | 1415 | * We also override seqno set by upper layer with the one |
1416 | * in tx aggregation state. | 1416 | * in tx aggregation state. |
1417 | * | ||
1418 | * If fragmentation is on, the sequence number is | ||
1419 | * not overridden, since it has been | ||
1420 | * incremented by the fragmentation routine. | ||
1421 | * | ||
1422 | * FIXME: check if the fragmentation threshold exceeds | ||
1423 | * IEEE80211 max. | ||
1424 | */ | 1417 | */ |
1425 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 1418 | tid = ATH_AN_2_TID(an, bf->bf_tidno); |
1426 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << | 1419 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); |
1427 | IEEE80211_SEQ_SEQ_SHIFT); | ||
1428 | bf->bf_seqno = tid->seq_next; | 1420 | bf->bf_seqno = tid->seq_next; |
1429 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | 1421 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); |
1430 | } | 1422 | } |
@@ -1636,7 +1628,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1636 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | 1628 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; |
1637 | } | 1629 | } |
1638 | 1630 | ||
1639 | if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) | 1631 | if (ieee80211_is_data_qos(fc) && bf_isht(bf) && |
1632 | (sc->sc_flags & SC_OP_TXAGGR)) | ||
1640 | assign_aggr_tid_seqno(skb, bf); | 1633 | assign_aggr_tid_seqno(skb, bf); |
1641 | 1634 | ||
1642 | bf->bf_mpdu = skb; | 1635 | bf->bf_mpdu = skb; |
@@ -1780,7 +1773,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1780 | struct ath_wiphy *aphy = hw->priv; | 1773 | struct ath_wiphy *aphy = hw->priv; |
1781 | struct ath_softc *sc = aphy->sc; | 1774 | struct ath_softc *sc = aphy->sc; |
1782 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1775 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1783 | int hdrlen, padsize; | 1776 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1777 | int padpos, padsize; | ||
1784 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1778 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1785 | struct ath_tx_control txctl; | 1779 | struct ath_tx_control txctl; |
1786 | 1780 | ||
@@ -1792,7 +1786,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1792 | * BSSes. | 1786 | * BSSes. |
1793 | */ | 1787 | */ |
1794 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 1788 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
1795 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1796 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 1789 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
1797 | sc->tx.seq_no += 0x10; | 1790 | sc->tx.seq_no += 0x10; |
1798 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | 1791 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); |
@@ -1800,9 +1793,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1800 | } | 1793 | } |
1801 | 1794 | ||
1802 | /* Add the padding after the header if this is not already done */ | 1795 | /* Add the padding after the header if this is not already done */ |
1803 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1796 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1804 | if (hdrlen & 3) { | 1797 | padsize = padpos & 3; |
1805 | padsize = hdrlen % 4; | 1798 | if (padsize && skb->len>padpos) { |
1806 | if (skb_headroom(skb) < padsize) { | 1799 | if (skb_headroom(skb) < padsize) { |
1807 | ath_print(common, ATH_DBG_XMIT, | 1800 | ath_print(common, ATH_DBG_XMIT, |
1808 | "TX CABQ padding failed\n"); | 1801 | "TX CABQ padding failed\n"); |
@@ -1810,7 +1803,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1810 | return; | 1803 | return; |
1811 | } | 1804 | } |
1812 | skb_push(skb, padsize); | 1805 | skb_push(skb, padsize); |
1813 | memmove(skb->data, skb->data + padsize, hdrlen); | 1806 | memmove(skb->data, skb->data + padsize, padpos); |
1814 | } | 1807 | } |
1815 | 1808 | ||
1816 | txctl.txq = sc->beacon.cabq; | 1809 | txctl.txq = sc->beacon.cabq; |
@@ -1838,7 +1831,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1838 | struct ieee80211_hw *hw = sc->hw; | 1831 | struct ieee80211_hw *hw = sc->hw; |
1839 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1832 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1840 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1833 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1841 | int hdrlen, padsize; | 1834 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
1835 | int padpos, padsize; | ||
1842 | 1836 | ||
1843 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1837 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1844 | 1838 | ||
@@ -1853,14 +1847,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1853 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 1847 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
1854 | } | 1848 | } |
1855 | 1849 | ||
1856 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1850 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1857 | padsize = hdrlen & 3; | 1851 | padsize = padpos & 3; |
1858 | if (padsize && hdrlen >= 24) { | 1852 | if (padsize && skb->len>padpos+padsize) { |
1859 | /* | 1853 | /* |
1860 | * Remove MAC header padding before giving the frame back to | 1854 | * Remove MAC header padding before giving the frame back to |
1861 | * mac80211. | 1855 | * mac80211. |
1862 | */ | 1856 | */ |
1863 | memmove(skb->data + padsize, skb->data, hdrlen); | 1857 | memmove(skb->data + padsize, skb->data, padpos); |
1864 | skb_pull(skb, padsize); | 1858 | skb_pull(skb, padsize); |
1865 | } | 1859 | } |
1866 | 1860 | ||
@@ -2078,7 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2078 | &txq->axq_q, lastbf->list.prev); | 2072 | &txq->axq_q, lastbf->list.prev); |
2079 | 2073 | ||
2080 | txq->axq_depth--; | 2074 | txq->axq_depth--; |
2081 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_FILT); | 2075 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); |
2082 | txq->axq_tx_inprogress = false; | 2076 | txq->axq_tx_inprogress = false; |
2083 | spin_unlock_bh(&txq->axq_lock); | 2077 | spin_unlock_bh(&txq->axq_lock); |
2084 | 2078 | ||