aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoit Papillault <benoit.papillault@free.fr>2009-12-11 18:22:35 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 11:32:00 -0500
commit4d91f9f3730d6d82a3ba67cae215a1823ba6a191 (patch)
treeb3784db7bc8b1c4eeb814f1c2e7c2ba182c140bb
parent521d9bce86331d8261213b807a9127f7e2ec046b (diff)
ath9k: Last fix for TX software padding.
First, we copy/paste the padding stuff from ath9k_tx to ath_tx_cabq since it needs to same kind of padding, but for internally generated beacons. Next, software padding done on TX needs to be removed before calling ieee80211_tx_status. The code was already there in ath_tx_complete but it was wrong. Fix it by using ath9k_cmn_padpos. This later code has been tested by sending packets to a monitor interface and reading packets from the same interface. Signed-off-by: Benoit PAPILLAULT <benoit.papillault@free.fr> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2a11cc57ceea..67706205699b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1780,7 +1780,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
1780 struct ath_wiphy *aphy = hw->priv; 1780 struct ath_wiphy *aphy = hw->priv;
1781 struct ath_softc *sc = aphy->sc; 1781 struct ath_softc *sc = aphy->sc;
1782 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1782 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1783 int hdrlen, padsize; 1783 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1784 int padpos, padsize;
1784 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1785 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1785 struct ath_tx_control txctl; 1786 struct ath_tx_control txctl;
1786 1787
@@ -1792,7 +1793,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
1792 * BSSes. 1793 * BSSes.
1793 */ 1794 */
1794 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1795 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) 1796 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
1797 sc->tx.seq_no += 0x10; 1797 sc->tx.seq_no += 0x10;
1798 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 1798 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -1800,9 +1800,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
1800 } 1800 }
1801 1801
1802 /* Add the padding after the header if this is not already done */ 1802 /* Add the padding after the header if this is not already done */
1803 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1803 padpos = ath9k_cmn_padpos(hdr->frame_control);
1804 if (hdrlen & 3) { 1804 padsize = padpos & 3;
1805 padsize = hdrlen % 4; 1805 if (padsize && skb->len>padpos) {
1806 if (skb_headroom(skb) < padsize) { 1806 if (skb_headroom(skb) < padsize) {
1807 ath_print(common, ATH_DBG_XMIT, 1807 ath_print(common, ATH_DBG_XMIT,
1808 "TX CABQ padding failed\n"); 1808 "TX CABQ padding failed\n");
@@ -1810,7 +1810,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
1810 return; 1810 return;
1811 } 1811 }
1812 skb_push(skb, padsize); 1812 skb_push(skb, padsize);
1813 memmove(skb->data, skb->data + padsize, hdrlen); 1813 memmove(skb->data, skb->data + padsize, padpos);
1814 } 1814 }
1815 1815
1816 txctl.txq = sc->beacon.cabq; 1816 txctl.txq = sc->beacon.cabq;
@@ -1838,7 +1838,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1838 struct ieee80211_hw *hw = sc->hw; 1838 struct ieee80211_hw *hw = sc->hw;
1839 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1839 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1840 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1840 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1841 int hdrlen, padsize; 1841 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1842 int padpos, padsize;
1842 1843
1843 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); 1844 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
1844 1845
@@ -1853,14 +1854,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1853 tx_info->flags |= IEEE80211_TX_STAT_ACK; 1854 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1854 } 1855 }
1855 1856
1856 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 1857 padpos = ath9k_cmn_padpos(hdr->frame_control);
1857 padsize = hdrlen & 3; 1858 padsize = padpos & 3;
1858 if (padsize && hdrlen >= 24) { 1859 if (padsize && skb->len>padpos+padsize) {
1859 /* 1860 /*
1860 * Remove MAC header padding before giving the frame back to 1861 * Remove MAC header padding before giving the frame back to
1861 * mac80211. 1862 * mac80211.
1862 */ 1863 */
1863 memmove(skb->data + padsize, skb->data, hdrlen); 1864 memmove(skb->data + padsize, skb->data, padpos);
1864 skb_pull(skb, padsize); 1865 skb_pull(skb, padsize);
1865 } 1866 }
1866 1867