|
@@ -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)
|
|
* 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)
|
|
}
|
|
}
|
|
|
|
|
|
/* 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);
|
|
|
|
- if (hdrlen & 3) {
|
|
|
|
- padsize = hdrlen % 4;
|
|
|
|
|
|
+ padpos = ath9k_cmn_padpos(hdr->frame_control);
|
|
|
|
+ padsize = padpos & 3;
|
|
|
|
+ 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)
|
|
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,
|
|
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,
|
|
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
|
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
|
}
|
|
}
|
|
|
|
|
|
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
|
|
|
|
- padsize = hdrlen & 3;
|
|
|
|
- if (padsize && hdrlen >= 24) {
|
|
|
|
|
|
+ padpos = ath9k_cmn_padpos(hdr->frame_control);
|
|
|
|
+ padsize = padpos & 3;
|
|
|
|
+ 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);
|
|
}
|
|
}
|
|
|
|
|