ath9k: Fix TX fragmentation
authorSujith Manoharan <c_manoha@qca.qualcomm.com>
Tue, 17 Apr 2012 03:04:50 +0000 (08:34 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 17 Apr 2012 18:17:05 +0000 (14:17 -0400)
Assigning sequence number for frames without taking care
of the fragment field breaks transmission of fragmented frames.
Fix this by assigning the fragment number properly.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/xmit.c

index 834e6bc45e8b13eb2b5175043287ee5d381f622e..23eaa1b26ebe5ca9a1a242ea4de5e9fa6508b02c 100644 (file)
@@ -1820,6 +1820,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
        struct ath_frame_info *fi = get_frame_info(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ath_buf *bf;
+       int fragno;
        u16 seqno;
 
        bf = ath_tx_get_buffer(sc);
@@ -1831,9 +1832,16 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
        ATH_TXBUF_RESET(bf);
 
        if (tid) {
+               fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
                seqno = tid->seq_next;
                hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
-               INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+
+               if (fragno)
+                       hdr->seq_ctrl |= cpu_to_le16(fragno);
+
+               if (!ieee80211_has_morefrags(hdr->frame_control))
+                       INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+
                bf->bf_state.seqno = seqno;
        }