aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2011-09-27 04:00:08 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2011-09-27 14:24:12 -0400
commit00b1edf16960695d820607845797b14e6ed1a26c (patch)
treeb68fa2775d94d3302df06919d099520a24a83a1e /drivers/net/wireless/ath/ath6kl
parentaad9339fa2a5e5b51874cfec9883819f59090198 (diff)
ath6kl: fix TCP corruption
Commit 94e532d1a ("ath6kl: Fix system freeze under heavy data load") aligns the skb data without checking if the skb is cloned. Because of this ath6kl can corrupt the local TCP stack information that can result in TCP retransmission failing and TCP connections stalling. To avoid the corruption we need to copy the skb. Now the alignment in ath6kl_htc_tx_buf_align() doesn't corrupt TCP packets anymore (and is not even used for the cloned skb's that got copied since the alignment of the data is handled at the copy time). Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl')
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 348c6463fe00..0869ff396b57 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -317,6 +317,24 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
317 317
318 spin_unlock_bh(&ar->lock); 318 spin_unlock_bh(&ar->lock);
319 319
320 if (!IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) &&
321 skb_cloned(skb)) {
322 /*
323 * We will touch (move the buffer data to align it. Since the
324 * skb buffer is cloned and not only the header is changed, we
325 * have to copy it to allow the changes. Since we are copying
326 * the data here, we may as well align it by reserving suitable
327 * headroom to avoid the memmove in ath6kl_htc_tx_buf_align().
328 */
329 struct sk_buff *nskb;
330
331 nskb = skb_copy_expand(skb, HTC_HDR_LENGTH, 0, GFP_ATOMIC);
332 if (nskb == NULL)
333 goto fail_tx;
334 kfree_skb(skb);
335 skb = nskb;
336 }
337
320 cookie->skb = skb; 338 cookie->skb = skb;
321 cookie->map_no = map_no; 339 cookie->map_no = map_no;
322 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, 340 set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,