diff options
author | Rajkumar Manoharan <rmanohar@qti.qualcomm.com> | 2016-08-09 12:01:51 +0530 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2016-09-02 18:34:33 +0300 |
commit | 7d42298eb43d27442e64d1e52e9f55f9cf9387e1 (patch) | |
tree | 353623dbfda20351e735a46a7be3e609447a8207 /drivers | |
parent | 75b34800a228b5cadc7196485fa0fdabfb9e7684 (diff) | |
download | linux-7d42298eb43d27442e64d1e52e9f55f9cf9387e1.tar.gz linux-7d42298eb43d27442e64d1e52e9f55f9cf9387e1.tar.bz2 linux-7d42298eb43d27442e64d1e52e9f55f9cf9387e1.zip |
ath10k: fix group privacy action frame decryption for qca4019
Recent commit 46f6b06050b7 ("mac80211: Encrypt "Group addressed privacy" action
frames") encrypts group privacy action frames. But qca99x0 family chipset
delivers broadcast/multicast management frames as encrypted and it should be
decrypted by mac80211. Setting RX_FLAG_DECRYPTED stats for those frames is
breaking mesh connection establishment.
Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 29 |
3 files changed, 33 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index f46f91648b06..ffedc0386c67 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -182,6 +182,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .board_size = QCA99X0_BOARD_DATA_SZ, .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, }, + .sw_decrypt_mcast_mgmt = true, }, { .id = QCA9984_HW_1_0_DEV_VERSION, @@ -205,6 +206,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .board_size = QCA99X0_BOARD_DATA_SZ, .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, }, + .sw_decrypt_mcast_mgmt = true, }, { .id = QCA9888_HW_2_0_DEV_VERSION, @@ -227,6 +229,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .board_size = QCA99X0_BOARD_DATA_SZ, .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, }, + .sw_decrypt_mcast_mgmt = true, }, { .id = QCA9377_HW_1_0_DEV_VERSION, @@ -285,6 +288,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .board_size = QCA4019_BOARD_DATA_SZ, .board_ext_size = QCA4019_BOARD_EXT_DATA_SZ, }, + .sw_decrypt_mcast_mgmt = true, }, }; diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 56daeb7926f9..7e329dcf9f4d 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -771,6 +771,11 @@ struct ath10k { size_t board_size; size_t board_ext_size; } fw; + + /* qca99x0 family chips deliver broadcast/multicast management + * frames encrypted and expect software do decryption. + */ + bool sw_decrypt_mcast_mgmt; } hw_params; /* contains the firmware images used with ATH10K_FIRMWARE_MODE_NORMAL */ diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index b9a3b09ec38a..4b4bf23a398d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2243,6 +2243,29 @@ static int ath10k_wmi_10_4_op_pull_mgmt_rx_ev(struct ath10k *ar, return 0; } +static bool ath10k_wmi_rx_is_decrypted(struct ath10k *ar, + struct ieee80211_hdr *hdr) +{ + if (!ieee80211_has_protected(hdr->frame_control)) + return false; + + /* FW delivers WEP Shared Auth frame with Protected Bit set and + * encrypted payload. However in case of PMF it delivers decrypted + * frames with Protected Bit set. + */ + if (ieee80211_is_auth(hdr->frame_control)) + return false; + + /* qca99x0 based FW delivers broadcast or multicast management frames + * (ex: group privacy action frames in mesh) as encrypted payload. + */ + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) && + ar->hw_params.sw_decrypt_mcast_mgmt) + return false; + + return true; +} + int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_mgmt_rx_ev_arg arg = {}; @@ -2329,11 +2352,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_handle_wep_reauth(ar, skb, status); - /* FW delivers WEP Shared Auth frame with Protected Bit set and - * encrypted payload. However in case of PMF it delivers decrypted - * frames with Protected Bit set. */ - if (ieee80211_has_protected(hdr->frame_control) && - !ieee80211_is_auth(hdr->frame_control)) { + if (ath10k_wmi_rx_is_decrypted(ar, hdr)) { status->flag |= RX_FLAG_DECRYPTED; if (!ieee80211_is_action(hdr->frame_control) && |