aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2016-01-28 07:25:33 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2016-02-27 15:00:15 -0500
commite29cc6b9c99639d9502bde0693afd3e49ec1ffd7 (patch)
treef97449a29fdd2e1cc6ff7df2391b69430440a6d6
parent283115fb1dcf6b2162e988db98e156b998a5ebb3 (diff)
iwlwifi: mvm: take care of padded packets
To ensure that the SNAP/TCP/IP headers are DW aligned, the firmware may add 2-byte pad at the end of the mac header - after the IV, before the SNAP. In that case the mpdu descriptor pad bit will be turned on. Driver should take it into consideration, and remove the padding before passing the packet to mac80211. Do that. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 590fc6faff04..cd6ca374e5d3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as 13 * it under the terms of version 2 of the GNU General Public License as
@@ -29,7 +29,7 @@
29 * 29 *
30 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 30 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32 * Copyright(c) 2015 Intel Deutschland GmbH 32 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
33 * All rights reserved. 33 * All rights reserved.
34 * 34 *
35 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
@@ -156,7 +156,14 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
156 u16 len, u8 crypt_len, 156 u16 len, u8 crypt_len,
157 struct iwl_rx_cmd_buffer *rxb) 157 struct iwl_rx_cmd_buffer *rxb)
158{ 158{
159 unsigned int hdrlen, fraglen; 159 struct iwl_rx_packet *pkt = rxb_addr(rxb);
160 struct iwl_rx_mpdu_desc *desc = (void *)pkt->data;
161 unsigned int headlen, fraglen, pad_len = 0;
162 unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);
163
164 if (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD)
165 pad_len = 2;
166 len -= pad_len;
160 167
161 /* If frame is small enough to fit in skb->head, pull it completely. 168 /* If frame is small enough to fit in skb->head, pull it completely.
162 * If not, only pull ieee80211_hdr (including crypto if present, and 169 * If not, only pull ieee80211_hdr (including crypto if present, and
@@ -170,14 +177,23 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
170 * If the latter changes (there are efforts in the standards group 177 * If the latter changes (there are efforts in the standards group
171 * to do so) we should revisit this and ieee80211_data_to_8023(). 178 * to do so) we should revisit this and ieee80211_data_to_8023().
172 */ 179 */
173 hdrlen = (len <= skb_tailroom(skb)) ? len : 180 headlen = (len <= skb_tailroom(skb)) ? len :
174 sizeof(*hdr) + crypt_len + 8; 181 hdrlen + crypt_len + 8;
175 182
183 /* The firmware may align the packet to DWORD.
184 * The padding is inserted after the IV.
185 * After copying the header + IV skip the padding if
186 * present before copying packet data.
187 */
188 hdrlen += crypt_len;
176 memcpy(skb_put(skb, hdrlen), hdr, hdrlen); 189 memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
177 fraglen = len - hdrlen; 190 memcpy(skb_put(skb, headlen - hdrlen), (u8 *)hdr + hdrlen + pad_len,
191 headlen - hdrlen);
192
193 fraglen = len - headlen;
178 194
179 if (fraglen) { 195 if (fraglen) {
180 int offset = (void *)hdr + hdrlen - 196 int offset = (void *)hdr + headlen + pad_len -
181 rxb_addr(rxb) + rxb_offset(rxb); 197 rxb_addr(rxb) + rxb_offset(rxb);
182 198
183 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, 199 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,