summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath11k/wow.c
diff options
context:
space:
mode:
authorCarl Huang <quic_cjhuang@quicinc.com>2022-03-14 06:18:16 +0100
committerKalle Valo <quic_kvalo@quicinc.com>2022-03-18 16:36:23 +0100
commita16d9b50cfbaf112401b8e5ccfa852709f498cd4 (patch)
treea611627e7743a84a7dcfa7bd65b4ccd5a45a3be2 /drivers/net/wireless/ath/ath11k/wow.c
parentath11k: support ARP and NS offload (diff)
downloadlinux-a16d9b50cfbaf112401b8e5ccfa852709f498cd4.tar.xz
linux-a16d9b50cfbaf112401b8e5ccfa852709f498cd4.zip
ath11k: support GTK rekey offload
Host sets GTK related info to firmware before WoW is enabled, and gets rekey replay_count and then disables GTK rekey when WoW quits. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang <quic_cjhuang@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://lore.kernel.org/r/1644308006-22784-7-git-send-email-quic_cjhuang@quicinc.com
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/wow.c')
-rw-r--r--drivers/net/wireless/ath/ath11k/wow.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c
index bc6a4d3d6d7c..93714df834b2 100644
--- a/drivers/net/wireless/ath/ath11k/wow.c
+++ b/drivers/net/wireless/ath/ath11k/wow.c
@@ -17,7 +17,9 @@
static const struct wiphy_wowlan_support ath11k_wowlan_support = {
.flags = WIPHY_WOWLAN_DISCONNECT |
- WIPHY_WOWLAN_MAGIC_PKT,
+ WIPHY_WOWLAN_MAGIC_PKT |
+ WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+ WIPHY_WOWLAN_GTK_REKEY_FAILURE,
.pattern_min_len = WOW_MIN_PATTERN_SIZE,
.pattern_max_len = WOW_MAX_PATTERN_SIZE,
.max_pkt_offset = WOW_MAX_PKT_OFFSET,
@@ -582,6 +584,41 @@ static int ath11k_wow_arp_ns_offload(struct ath11k *ar, bool enable)
return 0;
}
+static int ath11k_gtk_rekey_offload(struct ath11k *ar, bool enable)
+{
+ struct ath11k_vif *arvif;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (arvif->vdev_type != WMI_VDEV_TYPE_STA ||
+ !arvif->is_up ||
+ !arvif->rekey_data.enable_offload)
+ continue;
+
+ /* get rekey info before disable rekey offload */
+ if (!enable) {
+ ret = ath11k_wmi_gtk_rekey_getinfo(ar, arvif);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to request rekey info vdev %i, ret %d\n",
+ arvif->vdev_id, ret);
+ return ret;
+ }
+ }
+
+ ret = ath11k_wmi_gtk_rekey_offload(ar, arvif, enable);
+
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to offload gtk reky vdev %i: enable %d, ret %d\n",
+ arvif->vdev_id, enable, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int ath11k_wow_protocol_offload(struct ath11k *ar, bool enable)
{
int ret;
@@ -593,6 +630,13 @@ static int ath11k_wow_protocol_offload(struct ath11k *ar, bool enable)
return ret;
}
+ ret = ath11k_gtk_rekey_offload(ar, enable);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to offload gtk rekey %d %d\n",
+ enable, ret);
+ return ret;
+ }
+
return 0;
}