Commit 4d91f9f3 authored by Benoit Papillault's avatar Benoit Papillault Committed by John W. Linville

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: default avatarBenoit PAPILLAULT <benoit.papillault@free.fr>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 521d9bce
...@@ -1780,7 +1780,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1780,7 +1780,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
struct ath_wiphy *aphy = hw->priv; struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc; struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int hdrlen, padsize; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
int padpos, padsize;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath_tx_control txctl; struct ath_tx_control txctl;
...@@ -1792,7 +1793,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1792,7 +1793,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
* BSSes. * BSSes.
*/ */
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
sc->tx.seq_no += 0x10; sc->tx.seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 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,9 +1800,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
} }
/* Add the padding after the header if this is not already done */ /* Add the padding after the header if this is not already done */
hdrlen = ieee80211_get_hdrlen_from_skb(skb); padpos = ath9k_cmn_padpos(hdr->frame_control);
if (hdrlen & 3) { padsize = padpos & 3;
padsize = hdrlen % 4; if (padsize && skb->len>padpos) {
if (skb_headroom(skb) < padsize) { if (skb_headroom(skb) < padsize) {
ath_print(common, ATH_DBG_XMIT, ath_print(common, ATH_DBG_XMIT,
"TX CABQ padding failed\n"); "TX CABQ padding failed\n");
...@@ -1810,7 +1810,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1810,7 +1810,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
return; return;
} }
skb_push(skb, padsize); skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, hdrlen); memmove(skb->data, skb->data + padsize, padpos);
} }
txctl.txq = sc->beacon.cabq; txctl.txq = sc->beacon.cabq;
...@@ -1838,7 +1838,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1838,7 +1838,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ieee80211_hw *hw = sc->hw; struct ieee80211_hw *hw = sc->hw;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int hdrlen, padsize; struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
int padpos, padsize;
ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
...@@ -1853,14 +1854,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -1853,14 +1854,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
tx_info->flags |= IEEE80211_TX_STAT_ACK; tx_info->flags |= IEEE80211_TX_STAT_ACK;
} }
hdrlen = ieee80211_get_hdrlen_from_skb(skb); padpos = ath9k_cmn_padpos(hdr->frame_control);
padsize = hdrlen & 3; padsize = padpos & 3;
if (padsize && hdrlen >= 24) { if (padsize && skb->len>padpos+padsize) {
/* /*
* Remove MAC header padding before giving the frame back to * Remove MAC header padding before giving the frame back to
* mac80211. * mac80211.
*/ */
memmove(skb->data + padsize, skb->data, hdrlen); memmove(skb->data + padsize, skb->data, padpos);
skb_pull(skb, padsize); skb_pull(skb, padsize);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment