]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Jan 2018 09:40:25 +0000 (10:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Jan 2018 09:40:25 +0000 (10:40 +0100)
added patches:
ath10k-rebuild-crypto-header-in-rx-data-frames.patch
dm-bufio-fix-shrinker-scans-when-nr_to_scan-retain_target.patch
mac80211-add-rx-flag-to-indicate-icv-stripped.patch

queue-4.9/ath10k-rebuild-crypto-header-in-rx-data-frames.patch [new file with mode: 0644]
queue-4.9/dm-bufio-fix-shrinker-scans-when-nr_to_scan-retain_target.patch [new file with mode: 0644]
queue-4.9/mac80211-add-rx-flag-to-indicate-icv-stripped.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/ath10k-rebuild-crypto-header-in-rx-data-frames.patch b/queue-4.9/ath10k-rebuild-crypto-header-in-rx-data-frames.patch
new file mode 100644 (file)
index 0000000..70f5d06
--- /dev/null
@@ -0,0 +1,314 @@
+From 7eccb738fce57cbe53ed903ccf43f9ab257b15b3 Mon Sep 17 00:00:00 2001
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Date: Fri, 27 Oct 2017 18:35:31 +0300
+Subject: ath10k: rebuild crypto header in rx data frames
+
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+
+commit 7eccb738fce57cbe53ed903ccf43f9ab257b15b3 upstream.
+
+Rx data frames notified through HTT_T2H_MSG_TYPE_RX_IND and
+HTT_T2H_MSG_TYPE_RX_FRAG_IND expect PN/TSC check to be done
+on host (mac80211) rather than firmware. Rebuild cipher header
+in every received data frames (that are notified through those
+HTT interfaces) from the rx_hdr_status tlv available in the
+rx descriptor of the first msdu. Skip setting RX_FLAG_IV_STRIPPED
+flag for the packets which requires mac80211 PN/TSC check support
+and set appropriate RX_FLAG for stripped crypto tail. Hw QCA988X,
+QCA9887, QCA99X0, QCA9984, QCA9888 and QCA4019 currently need the
+rebuilding of cipher header to perform PN/TSC check for replay
+attack.
+
+Please note that removing crypto tail for CCMP-256, GCMP and GCMP-256 ciphers
+in raw mode needs to be fixed. Since Rx with these ciphers in raw
+mode does not work in the current form even without this patch and
+removing crypto tail for these chipers needs clean up, raw mode related
+issues in CCMP-256, GCMP and GCMP-256 can be addressed in follow up
+patches.
+
+Tested-by: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/htt_rx.c  |  105 +++++++++++++++++++++++++-----
+ drivers/net/wireless/ath/ath10k/rx_desc.h |    3 
+ 2 files changed, 92 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -548,6 +548,11 @@ static int ath10k_htt_rx_crypto_param_le
+               return IEEE80211_TKIP_IV_LEN;
+       case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
+               return IEEE80211_CCMP_HDR_LEN;
++      case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
++              return IEEE80211_CCMP_256_HDR_LEN;
++      case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
++      case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
++              return IEEE80211_GCMP_HDR_LEN;
+       case HTT_RX_MPDU_ENCRYPT_WEP128:
+       case HTT_RX_MPDU_ENCRYPT_WAPI:
+               break;
+@@ -573,6 +578,11 @@ static int ath10k_htt_rx_crypto_tail_len
+               return IEEE80211_TKIP_ICV_LEN;
+       case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
+               return IEEE80211_CCMP_MIC_LEN;
++      case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
++              return IEEE80211_CCMP_256_MIC_LEN;
++      case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
++      case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
++              return IEEE80211_GCMP_MIC_LEN;
+       case HTT_RX_MPDU_ENCRYPT_WEP128:
+       case HTT_RX_MPDU_ENCRYPT_WAPI:
+               break;
+@@ -1024,9 +1034,21 @@ static void ath10k_htt_rx_h_undecap_raw(
+       hdr = (void *)msdu->data;
+       /* Tail */
+-      if (status->flag & RX_FLAG_IV_STRIPPED)
++      if (status->flag & RX_FLAG_IV_STRIPPED) {
+               skb_trim(msdu, msdu->len -
+                        ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      } else {
++              /* MIC */
++              if ((status->flag & RX_FLAG_MIC_STRIPPED) &&
++                  enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
++                      skb_trim(msdu, msdu->len - 8);
++
++              /* ICV */
++              if (status->flag & RX_FLAG_ICV_STRIPPED &&
++                  enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
++                      skb_trim(msdu, msdu->len -
++                               ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      }
+       /* MMIC */
+       if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&
+@@ -1048,7 +1070,8 @@ static void ath10k_htt_rx_h_undecap_raw(
+ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
+                                         struct sk_buff *msdu,
+                                         struct ieee80211_rx_status *status,
+-                                        const u8 first_hdr[64])
++                                        const u8 first_hdr[64],
++                                        enum htt_rx_mpdu_encrypt_type enctype)
+ {
+       struct ieee80211_hdr *hdr;
+       struct htt_rx_desc *rxd;
+@@ -1056,6 +1079,7 @@ static void ath10k_htt_rx_h_undecap_nwif
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
+       int l3_pad_bytes;
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+       /* Delivered decapped frame:
+        * [nwifi 802.11 header] <-- replaced with 802.11 hdr
+@@ -1084,6 +1108,14 @@ static void ath10k_htt_rx_h_undecap_nwif
+       /* push original 802.11 header */
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+       /* original 802.11 header has a different DA and in
+@@ -1144,6 +1176,7 @@ static void ath10k_htt_rx_h_undecap_eth(
+       u8 sa[ETH_ALEN];
+       int l3_pad_bytes;
+       struct htt_rx_desc *rxd;
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+       /* Delivered decapped frame:
+        * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
+@@ -1172,6 +1205,14 @@ static void ath10k_htt_rx_h_undecap_eth(
+       /* push original 802.11 header */
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+       /* original 802.11 header has a different DA and in
+@@ -1185,12 +1226,14 @@ static void ath10k_htt_rx_h_undecap_eth(
+ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
+                                        struct sk_buff *msdu,
+                                        struct ieee80211_rx_status *status,
+-                                       const u8 first_hdr[64])
++                                       const u8 first_hdr[64],
++                                       enum htt_rx_mpdu_encrypt_type enctype)
+ {
+       struct ieee80211_hdr *hdr;
+       size_t hdr_len;
+       int l3_pad_bytes;
+       struct htt_rx_desc *rxd;
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+       /* Delivered decapped frame:
+        * [amsdu header] <-- replaced with 802.11 hdr
+@@ -1206,6 +1249,14 @@ static void ath10k_htt_rx_h_undecap_snap
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+ }
+@@ -1240,13 +1291,15 @@ static void ath10k_htt_rx_h_undecap(stru
+                                           is_decrypted);
+               break;
+       case RX_MSDU_DECAP_NATIVE_WIFI:
+-              ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr);
++              ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr,
++                                            enctype);
+               break;
+       case RX_MSDU_DECAP_ETHERNET2_DIX:
+               ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype);
+               break;
+       case RX_MSDU_DECAP_8023_SNAP_LLC:
+-              ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr);
++              ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr,
++                                           enctype);
+               break;
+       }
+ }
+@@ -1289,7 +1342,8 @@ static void ath10k_htt_rx_h_csum_offload
+ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+                                struct sk_buff_head *amsdu,
+-                               struct ieee80211_rx_status *status)
++                               struct ieee80211_rx_status *status,
++                               bool fill_crypt_header)
+ {
+       struct sk_buff *first;
+       struct sk_buff *last;
+@@ -1299,7 +1353,6 @@ static void ath10k_htt_rx_h_mpdu(struct
+       enum htt_rx_mpdu_encrypt_type enctype;
+       u8 first_hdr[64];
+       u8 *qos;
+-      size_t hdr_len;
+       bool has_fcs_err;
+       bool has_crypto_err;
+       bool has_tkip_err;
+@@ -1324,15 +1377,17 @@ static void ath10k_htt_rx_h_mpdu(struct
+        * decapped header. It'll be used for undecapping of each MSDU.
+        */
+       hdr = (void *)rxd->rx_hdr_status;
+-      hdr_len = ieee80211_hdrlen(hdr->frame_control);
+-      memcpy(first_hdr, hdr, hdr_len);
++      memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
+       /* Each A-MSDU subframe will use the original header as the base and be
+        * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
+        */
+       hdr = (void *)first_hdr;
+-      qos = ieee80211_get_qos_ctl(hdr);
+-      qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
++
++      if (ieee80211_is_data_qos(hdr->frame_control)) {
++              qos = ieee80211_get_qos_ctl(hdr);
++              qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
++      }
+       /* Some attention flags are valid only in the last MSDU. */
+       last = skb_peek_tail(amsdu);
+@@ -1379,9 +1434,14 @@ static void ath10k_htt_rx_h_mpdu(struct
+               status->flag |= RX_FLAG_DECRYPTED;
+               if (likely(!is_mgmt))
+-                      status->flag |= RX_FLAG_IV_STRIPPED |
+-                                      RX_FLAG_MMIC_STRIPPED;
+-}
++                      status->flag |= RX_FLAG_MMIC_STRIPPED;
++
++              if (fill_crypt_header)
++                      status->flag |= RX_FLAG_MIC_STRIPPED |
++                                      RX_FLAG_ICV_STRIPPED;
++              else
++                      status->flag |= RX_FLAG_IV_STRIPPED;
++      }
+       skb_queue_walk(amsdu, msdu) {
+               ath10k_htt_rx_h_csum_offload(msdu);
+@@ -1397,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct
+               if (is_mgmt)
+                       continue;
++              if (fill_crypt_header)
++                      continue;
++
+               hdr = (void *)msdu->data;
+               hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+       }
+@@ -1407,6 +1470,9 @@ static void ath10k_htt_rx_h_deliver(stru
+                                   struct ieee80211_rx_status *status)
+ {
+       struct sk_buff *msdu;
++      struct sk_buff *first_subframe;
++
++      first_subframe = skb_peek(amsdu);
+       while ((msdu = __skb_dequeue(amsdu))) {
+               /* Setup per-MSDU flags */
+@@ -1415,6 +1481,13 @@ static void ath10k_htt_rx_h_deliver(stru
+               else
+                       status->flag |= RX_FLAG_AMSDU_MORE;
++              if (msdu == first_subframe) {
++                      first_subframe = NULL;
++                      status->flag &= ~RX_FLAG_ALLOW_SAME_PN;
++              } else {
++                      status->flag |= RX_FLAG_ALLOW_SAME_PN;
++              }
++
+               ath10k_process_rx(ar, status, msdu);
+       }
+ }
+@@ -1557,7 +1630,7 @@ static int ath10k_htt_rx_handle_amsdu(st
+       ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
+       ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
+       ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
+-      ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
++      ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true);
+       ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
+       return num_msdus;
+@@ -1892,7 +1965,7 @@ static int ath10k_htt_rx_in_ord_ind(stru
+                       num_msdus += skb_queue_len(&amsdu);
+                       ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
+                       ath10k_htt_rx_h_filter(ar, &amsdu, status);
+-                      ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
++                      ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false);
+                       ath10k_htt_rx_h_deliver(ar, &amsdu, status);
+                       break;
+               case -EAGAIN:
+--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
+@@ -239,6 +239,9 @@ enum htt_rx_mpdu_encrypt_type {
+       HTT_RX_MPDU_ENCRYPT_WAPI             = 5,
+       HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2     = 6,
+       HTT_RX_MPDU_ENCRYPT_NONE             = 7,
++      HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2  = 8,
++      HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2    = 9,
++      HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2 = 10,
+ };
+ #define RX_MPDU_START_INFO0_PEER_IDX_MASK     0x000007ff
diff --git a/queue-4.9/dm-bufio-fix-shrinker-scans-when-nr_to_scan-retain_target.patch b/queue-4.9/dm-bufio-fix-shrinker-scans-when-nr_to_scan-retain_target.patch
new file mode 100644 (file)
index 0000000..3a5ef7b
--- /dev/null
@@ -0,0 +1,81 @@
+From fbc7c07ec23c040179384a1f16b62b6030eb6bdd Mon Sep 17 00:00:00 2001
+From: Suren Baghdasaryan <surenb@google.com>
+Date: Wed, 6 Dec 2017 09:27:30 -0800
+Subject: dm bufio: fix shrinker scans when (nr_to_scan < retain_target)
+
+From: Suren Baghdasaryan <surenb@google.com>
+
+commit fbc7c07ec23c040179384a1f16b62b6030eb6bdd upstream.
+
+When system is under memory pressure it is observed that dm bufio
+shrinker often reclaims only one buffer per scan. This change fixes
+the following two issues in dm bufio shrinker that cause this behavior:
+
+1. ((nr_to_scan - freed) <= retain_target) condition is used to
+terminate slab scan process. This assumes that nr_to_scan is equal
+to the LRU size, which might not be correct because do_shrink_slab()
+in vmscan.c calculates nr_to_scan using multiple inputs.
+As a result when nr_to_scan is less than retain_target (64) the scan
+will terminate after the first iteration, effectively reclaiming one
+buffer per scan and making scans very inefficient. This hurts vmscan
+performance especially because mutex is acquired/released every time
+dm_bufio_shrink_scan() is called.
+New implementation uses ((LRU size - freed) <= retain_target)
+condition for scan termination. LRU size can be safely determined
+inside __scan() because this function is called after dm_bufio_lock().
+
+2. do_shrink_slab() uses value returned by dm_bufio_shrink_count() to
+determine number of freeable objects in the slab. However dm_bufio
+always retains retain_target buffers in its LRU and will terminate
+a scan when this mark is reached. Therefore returning the entire LRU size
+from dm_bufio_shrink_count() is misleading because that does not
+represent the number of freeable objects that slab will reclaim during
+a scan. Returning (LRU size - retain_target) better represents the
+number of freeable objects in the slab. This way do_shrink_slab()
+returns 0 when (LRU size < retain_target) and vmscan will not try to
+scan this shrinker avoiding scans that will not reclaim any memory.
+
+Test: tested using Android device running
+<AOSP>/system/extras/alloc-stress that generates memory pressure
+and causes intensive shrinker scans
+
+Signed-off-by: Suren Baghdasaryan <surenb@google.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/md/dm-bufio.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -1554,7 +1554,8 @@ static unsigned long __scan(struct dm_bu
+       int l;
+       struct dm_buffer *b, *tmp;
+       unsigned long freed = 0;
+-      unsigned long count = nr_to_scan;
++      unsigned long count = c->n_buffers[LIST_CLEAN] +
++                            c->n_buffers[LIST_DIRTY];
+       unsigned long retain_target = get_retain_buffers(c);
+       for (l = 0; l < LIST_SIZE; l++) {
+@@ -1591,6 +1592,7 @@ dm_bufio_shrink_count(struct shrinker *s
+ {
+       struct dm_bufio_client *c;
+       unsigned long count;
++      unsigned long retain_target;
+       c = container_of(shrink, struct dm_bufio_client, shrinker);
+       if (sc->gfp_mask & __GFP_FS)
+@@ -1599,8 +1601,9 @@ dm_bufio_shrink_count(struct shrinker *s
+               return 0;
+       count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY];
++      retain_target = get_retain_buffers(c);
+       dm_bufio_unlock(c);
+-      return count;
++      return (count < retain_target) ? 0 : (count - retain_target);
+ }
+ /*
diff --git a/queue-4.9/mac80211-add-rx-flag-to-indicate-icv-stripped.patch b/queue-4.9/mac80211-add-rx-flag-to-indicate-icv-stripped.patch
new file mode 100644 (file)
index 0000000..4420dd3
--- /dev/null
@@ -0,0 +1,76 @@
+From cef0acd4d7d4811d2d19cd0195031bf0dfe41249 Mon Sep 17 00:00:00 2001
+From: David Spinadel <david.spinadel@intel.com>
+Date: Mon, 21 Nov 2016 16:58:40 +0200
+Subject: mac80211: Add RX flag to indicate ICV stripped
+
+From: David Spinadel <david.spinadel@intel.com>
+
+commit cef0acd4d7d4811d2d19cd0195031bf0dfe41249 upstream.
+
+Add a flag that indicates that the WEP ICV was stripped from an
+RX packet, allowing the device to not transfer that if it's
+already checked.
+
+Signed-off-by: David Spinadel <david.spinadel@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h |    5 ++++-
+ net/mac80211/wep.c     |    3 ++-
+ net/mac80211/wpa.c     |    3 ++-
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1007,7 +1007,7 @@ ieee80211_tx_info_clear_status(struct ie
+  * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware.
+  * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame,
+  *    verification has been done by the hardware.
+- * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame.
++ * @RX_FLAG_IV_STRIPPED: The IV and ICV are stripped from this frame.
+  *    If this flag is set, the stack cannot do any replay detection
+  *    hence the driver or hardware will have to do that.
+  * @RX_FLAG_PN_VALIDATED: Currently only valid for CCMP/GCMP frames, this
+@@ -1078,6 +1078,8 @@ ieee80211_tx_info_clear_status(struct ie
+  * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before.
+  *    This is used for AMSDU subframes which can have the same PN as
+  *    the first subframe.
++ * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
++ *    be done in the hardware.
+  */
+ enum mac80211_rx_flags {
+       RX_FLAG_MMIC_ERROR              = BIT(0),
+@@ -1113,6 +1115,7 @@ enum mac80211_rx_flags {
+       RX_FLAG_RADIOTAP_VENDOR_DATA    = BIT(31),
+       RX_FLAG_MIC_STRIPPED            = BIT_ULL(32),
+       RX_FLAG_ALLOW_SAME_PN           = BIT_ULL(33),
++      RX_FLAG_ICV_STRIPPED            = BIT_ULL(34),
+ };
+ #define RX_FLAG_STBC_SHIFT            26
+--- a/net/mac80211/wep.c
++++ b/net/mac80211/wep.c
+@@ -293,7 +293,8 @@ ieee80211_crypto_wep_decrypt(struct ieee
+                       return RX_DROP_UNUSABLE;
+               ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
+               /* remove ICV */
+-              if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
++              if (!(status->flag & RX_FLAG_ICV_STRIPPED) &&
++                  pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
+                       return RX_DROP_UNUSABLE;
+       }
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -295,7 +295,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
+               return RX_DROP_UNUSABLE;
+       /* Trim ICV */
+-      skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
++      if (!(status->flag & RX_FLAG_ICV_STRIPPED))
++              skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
+       /* Remove IV */
+       memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
index f77b2e574a3635722366215972ca4cb79b58894f..c00c41dee91068e4e11e7f56964b40ed91ed2f43 100644 (file)
@@ -1 +1,3 @@
 dm-bufio-fix-shrinker-scans-when-nr_to_scan-retain_target.patch
+mac80211-add-rx-flag-to-indicate-icv-stripped.patch
+ath10k-rebuild-crypto-header-in-rx-data-frames.patch