From 9ef0db4a69297bcc001c8d2588801bc489834b59 Mon Sep 17 00:00:00 2001
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Date: Mon, 14 Dec 2015 14:31:59 +0200
Subject: [PATCH] [BUGFIX] iwlwifi: pcie: correctly handle the IV in A-MSDU
[SQUASH]
The IV needs to be copied before it is pulled from the skb.
This prevented TSO to work properly with iv_len != 0.
type=bugfix
bug=not-tracked
fixes=I9d02be5b8349120e73d8997d91182aec2f42290f
Change-Id: Ieab88fdc18cd90066ff571ea2bd11ba79ea6f040
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
drivers/net/wireless/iwlwifi/pcie/tx.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
@@ -1977,15 +1977,10 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
&dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
NULL, 0);
- /*
- * Pull the ieee80211 header + IV to be able to use TSO core,
- * we will restore it for the tx_status flow.
- */
- skb_pull(skb, hdr_len + iv_len);
ip_hdrlen = skb_transport_header(skb) - skb_network_header(skb);
snap_ip_tcp_hdrlen =
IEEE80211_CCMP_HDR_LEN + ip_hdrlen + tcp_hdrlen(skb);
- total_len = skb->len - snap_ip_tcp_hdrlen;
+ total_len = skb->len - snap_ip_tcp_hdrlen - hdr_len - iv_len;
amsdu_pad = 0;
/* total amount of header we may need for this A-MSDU */
@@ -2000,9 +1995,15 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
get_page(hdr_page->page);
start_hdr = hdr_page->pos;
info->driver_data[IWL_TRANS_FIRST_DRIVER_DATA] = hdr_page->page;
- memcpy(hdr_page->pos, skb->data, iv_len);
+ memcpy(hdr_page->pos, skb->data + hdr_len, iv_len);
hdr_page->pos += iv_len;
+ /*
+ * Pull the ieee80211 header + IV to be able to use TSO core,
+ * we will restore it for the tx_status flow.
+ */
+ skb_pull(skb, hdr_len + iv_len);
+
tso_start(skb, &tso);
while (total_len) {
--
2.5.0