--- /dev/null
+From 2f38c3c01de945234d23dd163e3528ccb413066d Mon Sep 17 00:00:00 2001
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Date: Mon, 26 Sep 2016 21:56:24 +0300
+Subject: ath10k: fix rfc1042 header retrieval in QCA4019 with eth decap mode
+
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+
+commit 2f38c3c01de945234d23dd163e3528ccb413066d upstream.
+
+Chipset from QCA99X0 onwards (QCA99X0, QCA9984, QCA4019 & future)
+rx_hdr_status is not padded to align in 4-byte boundary. Define a
+new hw_params field to handle different alignment behaviour between
+different hw. This patch fixes improper retrieval of rfc1042 header
+with QCA4019. This patch along with "ath10k: Properly remove padding
+from the start of rx payload" will fix traffic failure in ethernet
+decap mode for QCA4019.
+
+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/ath/ath10k/core.c | 8 ++++++++
+ drivers/net/wireless/ath/ath10k/core.h | 4 ++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -67,6 +67,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA988X_BOARD_DATA_SZ,
+ .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ {
+ .id = QCA6174_HW_2_1_VERSION,
+@@ -85,6 +86,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA6174_BOARD_DATA_SZ,
+ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ {
+ .id = QCA6174_HW_2_1_VERSION,
+@@ -103,6 +105,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA6174_BOARD_DATA_SZ,
+ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ {
+ .id = QCA6174_HW_3_0_VERSION,
+@@ -121,6 +124,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA6174_BOARD_DATA_SZ,
+ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ {
+ .id = QCA6174_HW_3_2_VERSION,
+@@ -140,6 +144,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA6174_BOARD_DATA_SZ,
+ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ {
+ .id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -159,6 +164,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA99X0_BOARD_DATA_SZ,
+ .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 1,
+ },
+ {
+ .id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -177,6 +183,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA9377_BOARD_DATA_SZ,
+ .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ {
+ .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -195,6 +202,7 @@ static const struct ath10k_hw_params ath
+ .board_size = QCA9377_BOARD_DATA_SZ,
+ .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+ },
++ .decap_align_bytes = 4,
+ },
+ };
+
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -670,6 +670,10 @@ struct ath10k {
+ size_t board_size;
+ size_t board_ext_size;
+ } fw;
++
++ /* Number of bytes used for alignment in rx_hdr_status */
++ int decap_align_bytes;
++
+ } hw_params;
+
+ const struct firmware *board;
--- /dev/null
+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: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/ath/ath10k/htt_rx.c | 98 +++++++++++++++++++++++++------
+ 1 file changed, 82 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -1076,7 +1076,21 @@ static void ath10k_htt_rx_h_undecap_raw(
+ hdr = (void *)msdu->data;
+
+ /* Tail */
+- skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype));
++ 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 (!ieee80211_has_morefrags(hdr->frame_control) &&
+@@ -1095,12 +1109,14 @@ 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;
+ size_t hdr_len;
+ u8 da[ETH_ALEN];
+ u8 sa[ETH_ALEN];
++ int bytes_aligned = ar->hw_params.decap_align_bytes;
+
+ /* Delivered decapped frame:
+ * [nwifi 802.11 header] <-- replaced with 802.11 hdr
+@@ -1123,6 +1139,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
+@@ -1180,6 +1204,7 @@ static void ath10k_htt_rx_h_undecap_eth(
+ void *rfc1042;
+ u8 da[ETH_ALEN];
+ u8 sa[ETH_ALEN];
++ int bytes_aligned = ar->hw_params.decap_align_bytes;
+
+ /* Delivered decapped frame:
+ * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
+@@ -1203,6 +1228,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
+@@ -1216,10 +1249,12 @@ 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 bytes_aligned = ar->hw_params.decap_align_bytes;
+
+ /* Delivered decapped frame:
+ * [amsdu header] <-- replaced with 802.11 hdr
+@@ -1231,6 +1266,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);
+ }
+
+@@ -1265,13 +1308,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;
+ }
+ }
+@@ -1314,7 +1359,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;
+@@ -1324,7 +1370,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;
+@@ -1345,15 +1390,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);
+@@ -1387,11 +1434,17 @@ static void ath10k_htt_rx_h_mpdu(struct
+ if (has_tkip_err)
+ status->flag |= RX_FLAG_MMIC_ERROR;
+
+- if (is_decrypted)
++ if (is_decrypted) {
+ status->flag |= RX_FLAG_DECRYPTED |
+- RX_FLAG_IV_STRIPPED |
+ 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);
+ ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
+@@ -1404,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct
+ if (!is_decrypted)
+ continue;
+
++ if (fill_crypt_header)
++ continue;
++
+ hdr = (void *)msdu->data;
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ }
+@@ -1414,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 */
+@@ -1422,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);
+ }
+ }
+@@ -1607,7 +1673,7 @@ static void ath10k_htt_rx_handler(struct
+ 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);
+ }
+
+@@ -1653,7 +1719,7 @@ static void ath10k_htt_rx_frag_handler(s
+
+ ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
+ 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);
+
+ if (fw_desc_len > 0) {
+@@ -1952,7 +2018,7 @@ static void ath10k_htt_rx_in_ord_ind(str
+ */
+ 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:
--- /dev/null
+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: Sriram R <srirrama@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
+@@ -975,7 +975,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
+@@ -1034,6 +1034,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),
+@@ -1066,6 +1068,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
+@@ -298,7 +298,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);
--- /dev/null
+From f980ebc058c2fa2a552e495db1de0b330082ab70 Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Wed, 24 Feb 2016 11:49:45 +0200
+Subject: mac80211: allow not sending MIC up from driver for HW crypto
+
+From: Sara Sharon <sara.sharon@intel.com>
+
+commit f980ebc058c2fa2a552e495db1de0b330082ab70 upstream.
+
+When HW crypto is used, there's no need for the CCMP/GCMP MIC to
+be available to mac80211, and the hardware might have removed it
+already after checking. The MIC is also useless to have when the
+frame is already decrypted, so allow indicating that it's not
+present.
+
+Since we are running out of bits in mac80211_rx_flags, make
+the flags field a u64.
+
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Cc: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +-
+ drivers/net/wireless/ath/wcn36xx/txrx.c | 2 +-
+ include/net/mac80211.h | 5 ++++-
+ net/mac80211/util.c | 5 +++--
+ net/mac80211/wpa.c | 26 ++++++++++++++------------
+ 5 files changed, 23 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -979,7 +979,7 @@ static void ath10k_process_rx(struct ath
+ *status = *rx_status;
+
+ ath10k_dbg(ar, ATH10K_DBG_DATA,
+- "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
++ "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
+ skb,
+ skb->len,
+ ieee80211_get_SA(hdr),
+--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
++++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
+@@ -57,7 +57,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn,
+ RX_FLAG_MMIC_STRIPPED |
+ RX_FLAG_DECRYPTED;
+
+- wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag);
++ wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%llx\n", status.flag);
+
+ memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1013,6 +1013,8 @@ ieee80211_tx_info_clear_status(struct ie
+ * on this subframe
+ * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
+ * is stored in the @ampdu_delimiter_crc field)
++ * @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was
++ * done by the hardware
+ * @RX_FLAG_LDPC: LDPC was used
+ * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
+ * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
+@@ -1059,6 +1061,7 @@ enum mac80211_rx_flags {
+ RX_FLAG_5MHZ = BIT(29),
+ RX_FLAG_AMSDU_MORE = BIT(30),
+ RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31),
++ RX_FLAG_MIC_STRIPPED = BIT_ULL(32),
+ };
+
+ #define RX_FLAG_STBC_SHIFT 26
+@@ -1113,7 +1116,7 @@ struct ieee80211_rx_status {
+ u64 mactime;
+ u32 device_timestamp;
+ u32 ampdu_reference;
+- u32 flag;
++ u64 flag;
+ u16 freq;
+ u8 vht_flag;
+ u8 rate_idx;
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -2663,8 +2663,9 @@ u64 ieee80211_calculate_rx_timestamp(str
+
+ rate = cfg80211_calculate_bitrate(&ri);
+ if (WARN_ONCE(!rate,
+- "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+- status->flag, status->rate_idx, status->vht_nss))
++ "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
++ (unsigned long long)status->flag, status->rate_idx,
++ status->vht_nss))
+ return 0;
+
+ /* rewind from end of MPDU */
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -508,18 +508,20 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+ !ieee80211_is_robust_mgmt_frame(skb))
+ return RX_CONTINUE;
+
+- data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
+- if (!rx->sta || data_len < 0)
+- return RX_DROP_UNUSABLE;
+-
+ if (status->flag & RX_FLAG_DECRYPTED) {
+ if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
+ return RX_DROP_UNUSABLE;
++ if (status->flag & RX_FLAG_MIC_STRIPPED)
++ mic_len = 0;
+ } else {
+ if (skb_linearize(rx->skb))
+ return RX_DROP_UNUSABLE;
+ }
+
++ data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
++ if (!rx->sta || data_len < 0)
++ return RX_DROP_UNUSABLE;
++
+ if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
+ ccmp_hdr2pn(pn, skb->data + hdrlen);
+
+@@ -724,8 +726,7 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+ struct sk_buff *skb = rx->skb;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ u8 pn[IEEE80211_GCMP_PN_LEN];
+- int data_len;
+- int queue;
++ int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN;
+
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
+
+@@ -733,19 +734,20 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+ !ieee80211_is_robust_mgmt_frame(skb))
+ return RX_CONTINUE;
+
+- data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN -
+- IEEE80211_GCMP_MIC_LEN;
+- if (!rx->sta || data_len < 0)
+- return RX_DROP_UNUSABLE;
+-
+ if (status->flag & RX_FLAG_DECRYPTED) {
+ if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
+ return RX_DROP_UNUSABLE;
++ if (status->flag & RX_FLAG_MIC_STRIPPED)
++ mic_len = 0;
+ } else {
+ if (skb_linearize(rx->skb))
+ return RX_DROP_UNUSABLE;
+ }
+
++ data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len;
++ if (!rx->sta || data_len < 0)
++ return RX_DROP_UNUSABLE;
++
+ if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
+ gcmp_hdr2pn(pn, skb->data + hdrlen);
+
+@@ -776,7 +778,7 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+ }
+
+ /* Remove GCMP header and MIC */
+- if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN))
++ if (pskb_trim(skb, skb->len - mic_len))
+ return RX_DROP_UNUSABLE;
+ memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
+ skb_pull(skb, IEEE80211_GCMP_HDR_LEN);
--- /dev/null
+From f631a77ba920f7153a1094d09cd8f2ebbffd0328 Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Tue, 3 May 2016 15:59:44 +0300
+Subject: mac80211: allow same PN for AMSDU sub-frames
+
+From: Sara Sharon <sara.sharon@intel.com>
+
+commit f631a77ba920f7153a1094d09cd8f2ebbffd0328 upstream.
+
+Some hardware (iwlwifi an example) de-aggregate AMSDUs and copy the IV
+as is to the generated MPDUs, so the same PN appears in multiple
+packets without being a replay attack. Allow driver to explicitly
+indicate that a frame is allowed to have the same PN as the previous
+frame.
+
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Cc: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h | 6 +++++-
+ net/mac80211/wpa.c | 16 ++++++++++++----
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1031,6 +1031,9 @@ ieee80211_tx_info_clear_status(struct ie
+ * @RX_FLAG_RADIOTAP_VENDOR_DATA: This frame contains vendor-specific
+ * radiotap data in the skb->data (before the frame) as described by
+ * the &struct ieee80211_vendor_radiotap.
++ * @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.
+ */
+ enum mac80211_rx_flags {
+ RX_FLAG_MMIC_ERROR = BIT(0),
+@@ -1061,7 +1064,8 @@ enum mac80211_rx_flags {
+ RX_FLAG_5MHZ = BIT(29),
+ RX_FLAG_AMSDU_MORE = BIT(30),
+ RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31),
+- RX_FLAG_MIC_STRIPPED = BIT_ULL(32),
++ RX_FLAG_MIC_STRIPPED = BIT_ULL(32),
++ RX_FLAG_ALLOW_SAME_PN = BIT_ULL(33),
+ };
+
+ #define RX_FLAG_STBC_SHIFT 26
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -523,12 +523,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+ return RX_DROP_UNUSABLE;
+
+ if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
++ int res;
++
+ ccmp_hdr2pn(pn, skb->data + hdrlen);
+
+ queue = rx->security_idx;
+
+- if (memcmp(pn, key->u.ccmp.rx_pn[queue],
+- IEEE80211_CCMP_PN_LEN) <= 0) {
++ res = memcmp(pn, key->u.ccmp.rx_pn[queue],
++ IEEE80211_CCMP_PN_LEN);
++ if (res < 0 ||
++ (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+ key->u.ccmp.replays++;
+ return RX_DROP_UNUSABLE;
+ }
+@@ -749,12 +753,16 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+ return RX_DROP_UNUSABLE;
+
+ if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
++ int res;
++
+ gcmp_hdr2pn(pn, skb->data + hdrlen);
+
+ queue = rx->security_idx;
+
+- if (memcmp(pn, key->u.gcmp.rx_pn[queue],
+- IEEE80211_GCMP_PN_LEN) <= 0) {
++ res = memcmp(pn, key->u.gcmp.rx_pn[queue],
++ IEEE80211_GCMP_PN_LEN);
++ if (res < 0 ||
++ (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+ key->u.gcmp.replays++;
+ return RX_DROP_UNUSABLE;
+ }
asoc-samsung-i2s-ensure-the-rclk-rate-is-properly-determined.patch
bluetooth-btusb-add-device-id-for-rtl8822be.patch
kdb-make-mdr-command-repeat.patch
+mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch
+mac80211-allow-same-pn-for-amsdu-sub-frames.patch
+mac80211-add-rx-flag-to-indicate-icv-stripped.patch
+ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch
+ath10k-rebuild-crypto-header-in-rx-data-frames.patch