diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 72cc4f20d102..e355d5e4928d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -639,6 +639,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
639 | struct sk_buff *wmi_skb; | 639 | struct sk_buff *wmi_skb; |
640 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 640 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
641 | int len; | 641 | int len; |
642 | u32 buf_len = skb->len; | ||
642 | u16 fc; | 643 | u16 fc; |
643 | 644 | ||
644 | hdr = (struct ieee80211_hdr *)skb->data; | 645 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -648,6 +649,15 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
648 | return -EINVAL; | 649 | return -EINVAL; |
649 | 650 | ||
650 | len = sizeof(cmd->hdr) + skb->len; | 651 | len = sizeof(cmd->hdr) + skb->len; |
652 | |||
653 | if ((ieee80211_is_action(hdr->frame_control) || | ||
654 | ieee80211_is_deauth(hdr->frame_control) || | ||
655 | ieee80211_is_disassoc(hdr->frame_control)) && | ||
656 | ieee80211_has_protected(hdr->frame_control)) { | ||
657 | len += IEEE80211_CCMP_MIC_LEN; | ||
658 | buf_len += IEEE80211_CCMP_MIC_LEN; | ||
659 | } | ||
660 | |||
651 | len = round_up(len, 4); | 661 | len = round_up(len, 4); |
652 | 662 | ||
653 | wmi_skb = ath10k_wmi_alloc_skb(len); | 663 | wmi_skb = ath10k_wmi_alloc_skb(len); |
@@ -659,7 +669,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
659 | cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); | 669 | cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); |
660 | cmd->hdr.tx_rate = 0; | 670 | cmd->hdr.tx_rate = 0; |
661 | cmd->hdr.tx_power = 0; | 671 | cmd->hdr.tx_power = 0; |
662 | cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len)); | 672 | cmd->hdr.buf_len = __cpu_to_le32(buf_len); |
663 | 673 | ||
664 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); | 674 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); |
665 | memcpy(cmd->buf, skb->data, skb->len); | 675 | memcpy(cmd->buf, skb->data, skb->len); |
@@ -957,10 +967,16 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
957 | * frames with Protected Bit set. */ | 967 | * frames with Protected Bit set. */ |
958 | if (ieee80211_has_protected(hdr->frame_control) && | 968 | if (ieee80211_has_protected(hdr->frame_control) && |
959 | !ieee80211_is_auth(hdr->frame_control)) { | 969 | !ieee80211_is_auth(hdr->frame_control)) { |
960 | status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED | | 970 | status->flag |= RX_FLAG_DECRYPTED; |
961 | RX_FLAG_MMIC_STRIPPED; | 971 | |
962 | hdr->frame_control = __cpu_to_le16(fc & | 972 | if (!ieee80211_is_action(hdr->frame_control) && |
973 | !ieee80211_is_deauth(hdr->frame_control) && | ||
974 | !ieee80211_is_disassoc(hdr->frame_control)) { | ||
975 | status->flag |= RX_FLAG_IV_STRIPPED | | ||
976 | RX_FLAG_MMIC_STRIPPED; | ||
977 | hdr->frame_control = __cpu_to_le16(fc & | ||
963 | ~IEEE80211_FCTL_PROTECTED); | 978 | ~IEEE80211_FCTL_PROTECTED); |
979 | } | ||
964 | } | 980 | } |
965 | 981 | ||
966 | ath10k_dbg(ATH10K_DBG_MGMT, | 982 | ath10k_dbg(ATH10K_DBG_MGMT, |