diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a0cd51f28596..2c6aefad3728 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1017,6 +1017,8 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, while (bf) { struct sk_buff *skb = bf->bf_mpdu; struct ath_frame_info *fi = get_frame_info(skb); + struct ieee80211_hdr *hdr; + int padpos, padsize; info.type = get_hw_packet_type(skb); if (bf->bf_next) @@ -1024,8 +1026,20 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, else info.link = 0; - info.buf_addr[0] = bf->bf_buf_addr; - info.buf_len[0] = skb->len; + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + hdr = (struct ieee80211_hdr *)skb->data; + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = padpos + padsize; + info.buf_addr[1] = info.buf_addr[0] + padpos; + info.buf_len[1] = skb->len - padpos; + } else { + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = skb->len; + } + info.pkt_len = fi->framelen; info.keyix = fi->keyix; info.keytype = fi->keytype; @@ -1878,15 +1892,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } - /* Add the padding after the header if this is not already done */ - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len > padpos) { - if (skb_headroom(skb) < padsize) - return -ENOMEM; + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { + /* Add the padding after the header if this is not already done */ + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len > padpos) { + if (skb_headroom(skb) < padsize) + return -ENOMEM; - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, padpos); + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, padpos); + } } if ((vif && vif->type != NL80211_IFTYPE_AP && @@ -1936,15 +1952,17 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; - 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 - * mac80211. - */ - memmove(skb->data + padsize, skb->data, padpos); - skb_pull(skb, padsize); + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { + 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 + * mac80211. + */ + memmove(skb->data + padsize, skb->data, padpos); + skb_pull(skb, padsize); + } } if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { |