Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4245d313 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville
Browse files

ath9k: do not insert padding into tx buffers on AR9380+



With the new EDMA descriptor format, a single descriptor can contain up
to four buffer pointers. By splitting the buffer into two parts, we can
let the hardware add the padding internally instead of using memmove on
the skb data.

Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3afd21e7
Loading
Loading
Loading
Loading
+37 −19
Original line number Diff line number Diff line
@@ -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;

		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,6 +1892,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
	}

	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;
@@ -1888,6 +1903,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
			skb_push(skb, padsize);
			memmove(skb->data, skb->data + padsize, padpos);
		}
	}

	if ((vif && vif->type != NL80211_IFTYPE_AP &&
	            vif->type != NL80211_IFTYPE_AP_VLAN) ||
@@ -1936,6 +1952,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
		/* Frame was ACKed */
		tx_info->flags |= IEEE80211_TX_STAT_ACK;

	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) {
@@ -1946,6 +1963,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
			memmove(skb->data + padsize, skb->data, padpos);
			skb_pull(skb, padsize);
		}
	}

	if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
		sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;