|
@@ -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) {
|