All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan
@ 2021-06-01 15:09 Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 01/12] wcn36xx: Return result of set_power_params in suspend Bryan O'Donoghue
                   ` (12 more replies)
  0 siblings, 13 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

V5:
- Fixes a git rebase/squash error. A mutex_unlock for patch #2 was contained in
  patch #3 - Loic

V4:

A few functions need to be declared static which were only flagged by the
test robot when the V3 patches hit pending

- get_first_vif - Kernel test robot 
  Patch #2
  https://www.mail-archive.com/ath10k@lists.infradead.org/msg13558.html

- wcn36xx_ipv6_addr_change - Kernel test robot 
  https://www.mail-archive.com/ath10k@lists.infradead.org/msg13571.html
  Patch #5

- wcn36xx_set_rekey_data - Kernel test robot 
  Patch #7
  https://www.mail-archive.com/ath10k@lists.infradead.org/msg13559.html

Missed making this IPV6 only in the previous round

- Fixed an IPV6 optional compliation missed in V3 - Kernel test robot 
  https://www.mail-archive.com/ath10k@lists.infradead.org/msg13563.html
  Patch #6

Feedback from Ben and Loic

- Streamlines the finding of the first associated VIF - Loic Poulain
  Patch #2
  https://www.spinics.net/lists/linux-wireless/msg209208.html

- Adds Tested-by: Benjamin Li as indicated
  Patch *

I've verified this on Debian with 5.13.x and Android with 4.19.x where
4.19.x contains an appropriate out-of-tree LPM patch, to verify
suspend/resume with offloaded ARP in suspend for ipv4 and ipv6 still works.

V3:
- Ifdefs an IPV6 specific function which will not compile unless CONFIG_IPV6
  is switched on - Kernel test robot

V2:
- Drops work-around for scan in progress
  This is not required on a tip of tree kernel - Kalle
- Churn out "this patch" form commit logs - Kalle
- Adds comment about packing structures to commit log patch #8 - Kalle
- Moves enablement of magic-packet and GTK rekey to last patch
  This means that the functionality is only switched on when the full
  series has been applied - Kalle

https://www.spinics.net/lists/linux-wireless/msg206927.html

V1:
This series enables Wake on WLAN for the wcn36xx. Downstream implements two
competing methods for WoWLAN, only one of which is used in practice.

1. The downstream prima driver and firmware have a dedicated wowlan SMD
   command set, however for whatever reason, the downstream driver doesn't
   actually use that code path for suspend/resume.
   Similarly the downstream kernel will mask out the SMD interrupt when
   entering into suspend, so its clear the firmware assisted wowlan command
   is not used at all.
   In short, the code is implemented but not used.

2. The alternative version of wake on wlan implemented downstream does
   A. An RXP filter
   B. Frimware ipv4 ARP offload
   C. Frimware ipv6 namesapece offload
   D. GTK replay counter save/update on suspend/resume

This patchset replicates method #2 since it is the only method that
actually works. When replicating the functionality from downstream to
upsteam I found the RXP filter step to be redundant, so I skipped that.

Verified on Android/4.19 with qcom out-of-tree low-power patch on wcn3680.
Verified on Debian/kvalo/master on wcn3680 and wcn3620.

The Debian/upstream test doesn't include the low-power patches from qcom so
the time it takes the system to wake up when pinged is longer.

Test method:

1. Enable magic packet wakeup on target
   iw phy0 wowlan enable magic-packet
   iw phy0 wowlan show

2. Flush arp tables on host
   sudo ip -s -s neigh flush all
   sudo ip -6 -s -s neigh flush all

3. Suspend device
   echo 1 > /sys/kernel/debug/clk/debug_suspend
   echo mem > /sys/power/state ; cat /sys/kernel/debug/rpm_stats
   echo 0 > /sys/module/wcn36xx/parameters/debug_mask
   dmesg

4. Ping either ipv4 or ipv6
   ping 192.168.0.85
   ping -6 fe80::6455:44ff:fe33:2211%wlo1

In both cases using Wireshark we see the target system receive an ARP or
NS6 lookup and respond, followed by the host sending a ping or ping6 and
the target system coming out of suspend.

Similarly watching GTK keying on the AP when the device is in suspend, we
see the firmware successfully rekey and when we resume, the host picking up
the rekey material with persistence of the WiFi link during suspend/resume.

commit 5336fad96e8f ("wcn36xx: Enable firmware offloaded keepalive")
ensures that the link is kept alive in suspend, this additional set gives
the ability to 

- Resolve ARP/NS6 lookups without waking the system
- Rekeying in suspend
- Suspending and resuming based on received datagram

https://git.linaro.org/people/bryan.odonoghue/kernel.git/log/?h=ath.master-wcn36xx-fw-offload-suspend-resume

Bryan O'Donoghue (12):
  wcn36xx: Return result of set_power_params in suspend
  wcn36xx: Run suspend for the first ieee80211_vif
  wcn36xx: Add ipv4 ARP offload support in suspend
  wcn36xx: Do not flush indication queue on suspend/resume
  wcn36xx: Add ipv6 address tracking
  wcn36xx: Add ipv6 namespace offload in suspend
  wcn36xx: Add set_rekey_data callback
  wcn36xx: Add GTK offload to WoWLAN path
  wcn36xx: Add GTK offload info to WoWLAN resume
  wcn36xx: Add Host suspend indication support
  wcn36xx: Add host resume request support
  wcn36xx: Enable WOWLAN flags

 drivers/net/wireless/ath/wcn36xx/hal.h     |  20 +-
 drivers/net/wireless/ath/wcn36xx/main.c    | 110 ++++++++-
 drivers/net/wireless/ath/wcn36xx/smd.c     | 265 +++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h     |  17 ++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  14 ++
 5 files changed, 412 insertions(+), 14 deletions(-)

-- 
2.30.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 01/12] wcn36xx: Return result of set_power_params in suspend
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 02/12] wcn36xx: Run suspend for the first ieee80211_vif Bryan O'Donoghue
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

wcn36xx_smd_set_power_params() can return an error. For the purposes of
entering into suspend we need the suspend() function to trap and report
errors up the stack.

First step in this process is reporting the existing result code for
wcn36xx_smd_set_power_params().

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index afb4877eaad8..b361e40697a6 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1091,12 +1091,14 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
 static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 {
 	struct wcn36xx *wcn = hw->priv;
+	int ret;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n");
 
 	flush_workqueue(wcn->hal_ind_wq);
-	wcn36xx_smd_set_power_params(wcn, true);
-	return 0;
+	ret = wcn36xx_smd_set_power_params(wcn, true);
+
+	return ret;
 }
 
 static int wcn36xx_resume(struct ieee80211_hw *hw)
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 02/12] wcn36xx: Run suspend for the first ieee80211_vif
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 01/12] wcn36xx: Return result of set_power_params in suspend Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 03/12] wcn36xx: Add ipv4 ARP offload support in suspend Bryan O'Donoghue
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

A subsequent set of patches will extend out suspend/resume support in this
driver, we cannot set the firmware up for multiple ipv4/ipv6 addresses and
as such we can't iterate through a list of ieee80211_vif.

Constrain the interaction with the firmware to the first ieee80211_vif on
the suspend/resume/wowlan path.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 31 ++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index b361e40697a6..9a97a288a96f 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1088,15 +1088,34 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
 
 #ifdef CONFIG_PM
 
+static struct ieee80211_vif *wcn36xx_get_first_assoc_vif(struct wcn36xx *wcn)
+{
+	struct wcn36xx_vif *vif_priv = NULL;
+	struct ieee80211_vif *vif = NULL;
+
+	list_for_each_entry(vif_priv, &wcn->vif_list, list) {
+		if (vif_priv->sta_assoc) {
+			vif = wcn36xx_priv_to_vif(vif_priv);
+			break;
+		}
+	}
+	return vif;
+}
+
 static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 {
 	struct wcn36xx *wcn = hw->priv;
-	int ret;
+	struct ieee80211_vif *vif = NULL;
+	int ret = 0;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n");
 
 	flush_workqueue(wcn->hal_ind_wq);
-	ret = wcn36xx_smd_set_power_params(wcn, true);
+	mutex_lock(&wcn->conf_mutex);
+	vif = wcn36xx_get_first_assoc_vif(wcn);
+	if (vif)
+		ret = wcn36xx_smd_set_power_params(wcn, true);
+	mutex_unlock(&wcn->conf_mutex);
 
 	return ret;
 }
@@ -1104,11 +1123,17 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 static int wcn36xx_resume(struct ieee80211_hw *hw)
 {
 	struct wcn36xx *wcn = hw->priv;
+	struct ieee80211_vif *vif = NULL;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n");
 
 	flush_workqueue(wcn->hal_ind_wq);
-	wcn36xx_smd_set_power_params(wcn, false);
+	mutex_lock(&wcn->conf_mutex);
+	vif = wcn36xx_get_first_assoc_vif(wcn);
+	if (vif)
+		wcn36xx_smd_set_power_params(wcn, false);
+	mutex_unlock(&wcn->conf_mutex);
+
 	return 0;
 }
 
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 03/12] wcn36xx: Add ipv4 ARP offload support in suspend
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 01/12] wcn36xx: Return result of set_power_params in suspend Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 02/12] wcn36xx: Run suspend for the first ieee80211_vif Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 04/12] wcn36xx: Do not flush indication queue on suspend/resume Bryan O'Donoghue
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Add ARP offload support. Firmware is capable of responding to ARP requests
for a single ipv4 address only.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/hal.h  | 10 +++----
 drivers/net/wireless/ath/wcn36xx/main.c | 13 +++++++--
 drivers/net/wireless/ath/wcn36xx/smd.c  | 38 +++++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h  |  4 +++
 4 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index 65ef893f2736..b56c8292fa62 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -3465,7 +3465,7 @@ struct wcn36xx_hal_rem_bcn_filter_req {
 #define WCN36XX_HAL_OFFLOAD_ENABLE                          1
 #define WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE             0x2
 #define WCN36XX_HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE	\
-	(HAL_OFFLOAD_ENABLE|HAL_OFFLOAD_BCAST_FILTER_ENABLE)
+	(WCN36XX_HAL_OFFLOAD_ENABLE | WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE)
 
 struct wcn36xx_hal_ns_offload_params {
 	u8 src_ipv6_addr[WCN36XX_HAL_IPV6_ADDR_LEN];
@@ -3487,10 +3487,10 @@ struct wcn36xx_hal_ns_offload_params {
 	/* slot index for this offload */
 	u32 slot_index;
 	u8 bss_index;
-};
+} __packed;
 
 struct wcn36xx_hal_host_offload_req {
-	u8 offload_Type;
+	u8 offload_type;
 
 	/* enable or disable */
 	u8 enable;
@@ -3499,13 +3499,13 @@ struct wcn36xx_hal_host_offload_req {
 		u8 host_ipv4_addr[4];
 		u8 host_ipv6_addr[WCN36XX_HAL_IPV6_ADDR_LEN];
 	} u;
-};
+} __packed;
 
 struct wcn36xx_hal_host_offload_req_msg {
 	struct wcn36xx_hal_msg_header header;
 	struct wcn36xx_hal_host_offload_req host_offload_params;
 	struct wcn36xx_hal_ns_offload_params ns_offload_params;
-};
+} __packed;
 
 /* Packet Types. */
 #define WCN36XX_HAL_KEEP_ALIVE_NULL_PKT              1
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 9a97a288a96f..0da123660fa1 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1112,11 +1112,16 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 
 	flush_workqueue(wcn->hal_ind_wq);
 	mutex_lock(&wcn->conf_mutex);
+
 	vif = wcn36xx_get_first_assoc_vif(wcn);
-	if (vif)
+	if (vif) {
+		ret = wcn36xx_smd_arp_offload(wcn, vif, true);
+		if (ret)
+			goto out;
 		ret = wcn36xx_smd_set_power_params(wcn, true);
+	}
+out:
 	mutex_unlock(&wcn->conf_mutex);
-
 	return ret;
 }
 
@@ -1130,8 +1135,10 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 	flush_workqueue(wcn->hal_ind_wq);
 	mutex_lock(&wcn->conf_mutex);
 	vif = wcn36xx_get_first_assoc_vif(wcn);
-	if (vif)
+	if (vif) {
 		wcn36xx_smd_set_power_params(wcn, false);
+		wcn36xx_smd_arp_offload(wcn, vif, false);
+	}
 	mutex_unlock(&wcn->conf_mutex);
 
 	return 0;
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index d0c3a1557e8d..478e363610e1 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2756,6 +2756,43 @@ int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
 	return ret;
 }
 
+int wcn36xx_smd_arp_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+			    bool enable)
+{
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+	struct wcn36xx_hal_host_offload_req_msg msg_body;
+	int ret;
+
+	mutex_lock(&wcn->hal_mutex);
+
+	INIT_HAL_MSG(msg_body, WCN36XX_HAL_HOST_OFFLOAD_REQ);
+	msg_body.host_offload_params.offload_type =
+		WCN36XX_HAL_IPV4_ARP_REPLY_OFFLOAD;
+	if (enable) {
+		msg_body.host_offload_params.enable =
+			WCN36XX_HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE;
+		memcpy(&msg_body.host_offload_params.u,
+		       &vif->bss_conf.arp_addr_list[0], sizeof(__be32));
+	}
+	msg_body.ns_offload_params.bss_index = vif_priv->bss_index;
+
+	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+	ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+	if (ret) {
+		wcn36xx_err("Sending host_offload_arp failed\n");
+		goto out;
+	}
+	ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+	if (ret) {
+		wcn36xx_err("host_offload_arp failed err=%d\n", ret);
+		goto out;
+	}
+out:
+	mutex_unlock(&wcn->hal_mutex);
+	return ret;
+}
+
 int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 			    void *buf, int len, void *priv, u32 addr)
 {
@@ -2804,6 +2841,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 	case WCN36XX_HAL_8023_MULTICAST_LIST_RSP:
 	case WCN36XX_HAL_START_SCAN_OFFLOAD_RSP:
 	case WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP:
+	case WCN36XX_HAL_HOST_OFFLOAD_RSP:
 		memcpy(wcn->hal_buf, buf, len);
 		wcn->hal_rsp_len = len;
 		complete(&wcn->hal_rsp_compl);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 462860572e1f..6492a628ea6a 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -146,4 +146,8 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
 			    struct ieee80211_vif *vif,
 			    struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp);
+
+int wcn36xx_smd_arp_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+			    bool enable);
+
 #endif	/* _SMD_H_ */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 04/12] wcn36xx: Do not flush indication queue on suspend/resume
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (2 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 03/12] wcn36xx: Add ipv4 ARP offload support in suspend Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 05/12] wcn36xx: Add ipv6 address tracking Bryan O'Donoghue
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Testing on Android reveals that the flush on both suspend and resume of the
firmware indication work-queue can stall indefinitely.

Given this code path doesn't appear to have been exercised up until now,
removing this flush to unblock this situation.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 0da123660fa1..9731fcbe2e7f 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1110,7 +1110,6 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n");
 
-	flush_workqueue(wcn->hal_ind_wq);
 	mutex_lock(&wcn->conf_mutex);
 
 	vif = wcn36xx_get_first_assoc_vif(wcn);
@@ -1132,7 +1131,6 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n");
 
-	flush_workqueue(wcn->hal_ind_wq);
 	mutex_lock(&wcn->conf_mutex);
 	vif = wcn36xx_get_first_assoc_vif(wcn);
 	if (vif) {
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 05/12] wcn36xx: Add ipv6 address tracking
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (3 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 04/12] wcn36xx: Do not flush indication queue on suspend/resume Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 06/12] wcn36xx: Add ipv6 namespace offload in suspend Bryan O'Donoghue
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Taking code from iwlwifi this commit adds a standard callback for
ipv6_addr_change().

This callback allows wcn36xx to know the set of ipv6 addresses. Something
we need to know in order to get wowlan working with ipv6.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/hal.h     |  1 +
 drivers/net/wireless/ath/wcn36xx/main.c    | 32 ++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  8 ++++++
 3 files changed, 41 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index b56c8292fa62..90333daed845 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -3466,6 +3466,7 @@ struct wcn36xx_hal_rem_bcn_filter_req {
 #define WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE             0x2
 #define WCN36XX_HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE	\
 	(WCN36XX_HAL_OFFLOAD_ENABLE | WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE)
+#define WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX		0x02
 
 struct wcn36xx_hal_ns_offload_params {
 	u8 src_ipv6_addr[WCN36XX_HAL_IPV6_ADDR_LEN];
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 9731fcbe2e7f..240ecdd52f81 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -25,6 +25,7 @@
 #include <linux/rpmsg.h>
 #include <linux/soc/qcom/smem_state.h>
 #include <linux/soc/qcom/wcnss_ctrl.h>
+#include <net/ipv6.h>
 #include "wcn36xx.h"
 #include "testmode.h"
 
@@ -1208,6 +1209,34 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_IPV6)
+static void wcn36xx_ipv6_addr_change(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif,
+				     struct inet6_dev *idev)
+{
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+	struct inet6_ifaddr *ifa;
+	int idx = 0;
+
+	memset(vif_priv->tentative_addrs, 0, sizeof(vif_priv->tentative_addrs));
+
+	read_lock_bh(&idev->lock);
+	list_for_each_entry(ifa, &idev->addr_list, if_list) {
+		vif_priv->target_ipv6_addrs[idx] = ifa->addr;
+		if (ifa->flags & IFA_F_TENTATIVE)
+			__set_bit(idx, vif_priv->tentative_addrs);
+		idx++;
+		if (idx >= WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX)
+			break;
+		wcn36xx_dbg(WCN36XX_DBG_MAC, "%pI6 %s\n", &ifa->addr,
+			    (ifa->flags & IFA_F_TENTATIVE) ? "tentative" : NULL);
+	}
+	read_unlock_bh(&idev->lock);
+
+	vif_priv->num_target_ipv6_addrs = idx;
+}
+#endif
+
 static const struct ieee80211_ops wcn36xx_ops = {
 	.start			= wcn36xx_start,
 	.stop			= wcn36xx_stop,
@@ -1231,6 +1260,9 @@ static const struct ieee80211_ops wcn36xx_ops = {
 	.sta_add		= wcn36xx_sta_add,
 	.sta_remove		= wcn36xx_sta_remove,
 	.ampdu_action		= wcn36xx_ampdu_action,
+#if IS_ENABLED(CONFIG_IPV6)
+	.ipv6_addr_change	= wcn36xx_ipv6_addr_change,
+#endif
 
 	CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
 };
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 71fa9992b118..5a5114660b18 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -18,6 +18,7 @@
 #define _WCN36XX_H_
 
 #include <linux/completion.h>
+#include <linux/in6.h>
 #include <linux/printk.h>
 #include <linux/spinlock.h>
 #include <net/mac80211.h>
@@ -136,6 +137,13 @@ struct wcn36xx_vif {
 	u8 self_dpu_desc_index;
 	u8 self_ucast_dpu_sign;
 
+#if IS_ENABLED(CONFIG_IPV6)
+	/* IPv6 addresses for WoWLAN */
+	struct in6_addr target_ipv6_addrs[WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX];
+	unsigned long tentative_addrs[BITS_TO_LONGS(WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX)];
+	int num_target_ipv6_addrs;
+#endif
+
 	struct list_head sta_list;
 };
 
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 06/12] wcn36xx: Add ipv6 namespace offload in suspend
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (4 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 05/12] wcn36xx: Add ipv6 address tracking Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 07/12] wcn36xx: Add set_rekey_data callback Bryan O'Donoghue
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson,
	kernel test robot

We need to respond to ipv6 namespace lookups when in suspend. This patch
adds the necessary changes to issue the appropriate firmware command on
suspend and resume to enter/exit firmware offloaded ns lookup.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reported-by: kernel test robot <lkp@intel.com>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/hal.h  |  3 ++
 drivers/net/wireless/ath/wcn36xx/main.c |  4 ++
 drivers/net/wireless/ath/wcn36xx/smd.c  | 63 +++++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h  |  3 ++
 4 files changed, 73 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index 90333daed845..3b949b0b3792 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -3464,6 +3464,9 @@ struct wcn36xx_hal_rem_bcn_filter_req {
 #define WCN36XX_HAL_OFFLOAD_DISABLE                         0
 #define WCN36XX_HAL_OFFLOAD_ENABLE                          1
 #define WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE             0x2
+#define WCN36XX_HAL_OFFLOAD_MCAST_FILTER_ENABLE             0x4
+#define WCN36XX_HAL_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE	\
+	(WCN36XX_HAL_OFFLOAD_ENABLE | WCN36XX_HAL_OFFLOAD_MCAST_FILTER_ENABLE)
 #define WCN36XX_HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE	\
 	(WCN36XX_HAL_OFFLOAD_ENABLE | WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE)
 #define WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX		0x02
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 240ecdd52f81..09e22f829682 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1116,6 +1116,9 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 	vif = wcn36xx_get_first_assoc_vif(wcn);
 	if (vif) {
 		ret = wcn36xx_smd_arp_offload(wcn, vif, true);
+		if (ret)
+			goto out;
+		ret = wcn36xx_smd_ipv6_ns_offload(wcn, vif, true);
 		if (ret)
 			goto out;
 		ret = wcn36xx_smd_set_power_params(wcn, true);
@@ -1136,6 +1139,7 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 	vif = wcn36xx_get_first_assoc_vif(wcn);
 	if (vif) {
 		wcn36xx_smd_set_power_params(wcn, false);
+		wcn36xx_smd_ipv6_ns_offload(wcn, vif, false);
 		wcn36xx_smd_arp_offload(wcn, vif, false);
 	}
 	mutex_unlock(&wcn->conf_mutex);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 478e363610e1..4a50e5f8456a 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2793,6 +2793,69 @@ int wcn36xx_smd_arp_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_IPV6)
+int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+				bool enable)
+{
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+	struct wcn36xx_hal_host_offload_req_msg msg_body;
+	struct wcn36xx_hal_ns_offload_params *ns_params;
+	struct wcn36xx_hal_host_offload_req *ho_params;
+	int ret;
+
+	mutex_lock(&wcn->hal_mutex);
+
+	INIT_HAL_MSG(msg_body, WCN36XX_HAL_HOST_OFFLOAD_REQ);
+	ho_params = &msg_body.host_offload_params;
+	ns_params = &msg_body.ns_offload_params;
+
+	ho_params->offload_type = WCN36XX_HAL_IPV6_NS_OFFLOAD;
+	if (enable) {
+		ho_params->enable =
+			WCN36XX_HAL_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE;
+		if (vif_priv->num_target_ipv6_addrs) {
+			memcpy(&ho_params->u,
+			       &vif_priv->target_ipv6_addrs[0].in6_u,
+			       sizeof(struct in6_addr));
+			memcpy(&ns_params->target_ipv6_addr1,
+			       &vif_priv->target_ipv6_addrs[0].in6_u,
+			       sizeof(struct in6_addr));
+			ns_params->target_ipv6_addr1_valid = 1;
+		}
+		if (vif_priv->num_target_ipv6_addrs > 1) {
+			memcpy(&ns_params->target_ipv6_addr2,
+			       &vif_priv->target_ipv6_addrs[1].in6_u,
+			       sizeof(struct in6_addr));
+			ns_params->target_ipv6_addr2_valid = 1;
+		}
+	}
+	memcpy(&ns_params->self_addr, vif->addr, ETH_ALEN);
+	ns_params->bss_index = vif_priv->bss_index;
+
+	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+	ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+	if (ret) {
+		wcn36xx_err("Sending host_offload_arp failed\n");
+		goto out;
+	}
+	ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+	if (ret) {
+		wcn36xx_err("host_offload_arp failed err=%d\n", ret);
+		goto out;
+	}
+out:
+	mutex_unlock(&wcn->hal_mutex);
+	return ret;
+}
+#else
+int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+				bool enable)
+{
+	return 0;
+}
+#endif
+
 int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 			    void *buf, int len, void *priv, u32 addr)
 {
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 6492a628ea6a..e03ab7878432 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -150,4 +150,7 @@ int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
 int wcn36xx_smd_arp_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 			    bool enable);
 
+int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+				bool enable);
+
 #endif	/* _SMD_H_ */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 07/12] wcn36xx: Add set_rekey_data callback
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (5 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 06/12] wcn36xx: Add ipv6 namespace offload in suspend Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:09 ` [PATCH v5 08/12] wcn36xx: Add GTK offload to WoWLAN path Bryan O'Donoghue
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Add a callback for Group Temporal Key tracking as provided by the standard
WiFi ops structure.

We track the key to integrate GTK offloading into the WoWLAN suspend path
later on. Code comes from the Intel iwlwifi driver with minimal name
changes.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c    | 19 +++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  6 ++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 09e22f829682..ec32b8b0067d 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1147,6 +1147,24 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 	return 0;
 }
 
+static void wcn36xx_set_rekey_data(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   struct cfg80211_gtk_rekey_data *data)
+{
+	struct wcn36xx *wcn = hw->priv;
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+
+	mutex_lock(&wcn->conf_mutex);
+
+	memcpy(vif_priv->rekey_data.kek, data->kek, NL80211_KEK_LEN);
+	memcpy(vif_priv->rekey_data.kck, data->kck, NL80211_KCK_LEN);
+	vif_priv->rekey_data.replay_ctr =
+		cpu_to_le64(be64_to_cpup((__be64 *)data->replay_ctr));
+	vif_priv->rekey_data.valid = true;
+
+	mutex_unlock(&wcn->conf_mutex);
+}
+
 #endif
 
 static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
@@ -1249,6 +1267,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
 #ifdef CONFIG_PM
 	.suspend		= wcn36xx_suspend,
 	.resume			= wcn36xx_resume,
+	.set_rekey_data		= wcn36xx_set_rekey_data,
 #endif
 	.config			= wcn36xx_config,
 	.prepare_multicast	= wcn36xx_prepare_multicast,
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 5a5114660b18..6121d8a5641a 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -143,6 +143,12 @@ struct wcn36xx_vif {
 	unsigned long tentative_addrs[BITS_TO_LONGS(WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX)];
 	int num_target_ipv6_addrs;
 #endif
+	/* WoWLAN GTK rekey data */
+	struct {
+		u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
+		__le64 replay_ctr;
+		bool valid;
+	} rekey_data;
 
 	struct list_head sta_list;
 };
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 08/12] wcn36xx: Add GTK offload to WoWLAN path
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (6 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 07/12] wcn36xx: Add set_rekey_data callback Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-04  4:57   ` kernel test robot
  2021-06-01 15:09 ` [PATCH v5 09/12] wcn36xx: Add GTK offload info to WoWLAN resume Bryan O'Donoghue
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Using previously set GTK KCK and KEK material this commit adds GTK rekeying
to the WoWLAN suspend/resume path. A small error in the packing of the
up to now unused command structure is fixed as we go.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/hal.h  |  2 +-
 drivers/net/wireless/ath/wcn36xx/main.c |  4 +++
 drivers/net/wireless/ath/wcn36xx/smd.c  | 38 +++++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h  |  3 ++
 4 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index 3b949b0b3792..1f3c2e840232 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -4905,7 +4905,7 @@ struct wcn36xx_hal_gtk_offload_req_msg {
 	u64 key_replay_counter;
 
 	u8 bss_index;
-};
+} __packed;
 
 struct wcn36xx_hal_gtk_offload_rsp_msg {
 	struct wcn36xx_hal_msg_header header;
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index ec32b8b0067d..db1528a14757 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1119,6 +1119,9 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 		if (ret)
 			goto out;
 		ret = wcn36xx_smd_ipv6_ns_offload(wcn, vif, true);
+		if (ret)
+			goto out;
+		ret = wcn36xx_smd_gtk_offload(wcn, vif, true);
 		if (ret)
 			goto out;
 		ret = wcn36xx_smd_set_power_params(wcn, true);
@@ -1139,6 +1142,7 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 	vif = wcn36xx_get_first_assoc_vif(wcn);
 	if (vif) {
 		wcn36xx_smd_set_power_params(wcn, false);
+		wcn36xx_smd_gtk_offload(wcn, vif, false);
 		wcn36xx_smd_ipv6_ns_offload(wcn, vif, false);
 		wcn36xx_smd_arp_offload(wcn, vif, false);
 	}
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 4a50e5f8456a..f74cb16327d0 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2856,6 +2856,43 @@ int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 }
 #endif
 
+int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+			    bool enable)
+{
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+	struct wcn36xx_hal_gtk_offload_req_msg msg_body;
+	int ret;
+
+	mutex_lock(&wcn->hal_mutex);
+
+	INIT_HAL_MSG(msg_body, WCN36XX_HAL_GTK_OFFLOAD_REQ);
+
+	if (enable) {
+		memcpy(&msg_body.kek, vif_priv->rekey_data.kek, NL80211_KEK_LEN);
+		memcpy(&msg_body.kck, vif_priv->rekey_data.kck, NL80211_KCK_LEN);
+		msg_body.key_replay_counter = vif_priv->rekey_data.replay_ctr;
+		msg_body.bss_index = vif_priv->bss_index;
+	} else {
+		msg_body.flags = WCN36XX_HAL_GTK_OFFLOAD_FLAGS_DISABLE;
+	}
+
+	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+	ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+	if (ret) {
+		wcn36xx_err("Sending host_offload_arp failed\n");
+		goto out;
+	}
+	ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+	if (ret) {
+		wcn36xx_err("host_offload_arp failed err=%d\n", ret);
+		goto out;
+	}
+out:
+	mutex_unlock(&wcn->hal_mutex);
+	return ret;
+}
+
 int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 			    void *buf, int len, void *priv, u32 addr)
 {
@@ -2905,6 +2942,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 	case WCN36XX_HAL_START_SCAN_OFFLOAD_RSP:
 	case WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP:
 	case WCN36XX_HAL_HOST_OFFLOAD_RSP:
+	case WCN36XX_HAL_GTK_OFFLOAD_RSP:
 		memcpy(wcn->hal_buf, buf, len);
 		wcn->hal_rsp_len = len;
 		complete(&wcn->hal_rsp_compl);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index e03ab7878432..cdf4231efe26 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -153,4 +153,7 @@ int wcn36xx_smd_arp_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 				bool enable);
 
+int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
+			    bool enable);
+
 #endif	/* _SMD_H_ */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 09/12] wcn36xx: Add GTK offload info to WoWLAN resume
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (7 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 08/12] wcn36xx: Add GTK offload to WoWLAN path Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-04  6:13   ` kernel test robot
  2021-06-01 15:09 ` [PATCH v5 10/12] wcn36xx: Add Host suspend indication support Bryan O'Donoghue
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Having enabled GTK rekey in suspend, we need to extract the replay counter
from the firmware on resume and perform a ieee80211_gtk_rekey_notify() so
that the STA remains verified from the perspective of the AP.

In order to enable the SMD command and response we need to pack the
existing command/response structures. Given these structures are currently
unused, there's no need to backport this as a fix.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/hal.h  |  4 +-
 drivers/net/wireless/ath/wcn36xx/main.c |  1 +
 drivers/net/wireless/ath/wcn36xx/smd.c  | 72 +++++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h  |  3 ++
 4 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index 1f3c2e840232..455143c4164e 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -4919,7 +4919,7 @@ struct wcn36xx_hal_gtk_offload_rsp_msg {
 struct wcn36xx_hal_gtk_offload_get_info_req_msg {
 	struct wcn36xx_hal_msg_header header;
 	u8 bss_index;
-};
+} __packed;
 
 struct wcn36xx_hal_gtk_offload_get_info_rsp_msg {
 	struct wcn36xx_hal_msg_header header;
@@ -4943,7 +4943,7 @@ struct wcn36xx_hal_gtk_offload_get_info_rsp_msg {
 	u32 igtk_rekey_count;
 
 	u8 bss_index;
-};
+} __packed;
 
 struct dhcp_info {
 	/* Indicates the device mode which indicates about the DHCP activity */
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index db1528a14757..8e5d8326d551 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1142,6 +1142,7 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 	vif = wcn36xx_get_first_assoc_vif(wcn);
 	if (vif) {
 		wcn36xx_smd_set_power_params(wcn, false);
+		wcn36xx_smd_gtk_offload_get_info(wcn, vif);
 		wcn36xx_smd_gtk_offload(wcn, vif, false);
 		wcn36xx_smd_ipv6_ns_offload(wcn, vif, false);
 		wcn36xx_smd_arp_offload(wcn, vif, false);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index f74cb16327d0..e249971c4ef7 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2893,6 +2893,77 @@ int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 	return ret;
 }
 
+static int wcn36xx_smd_gtk_offload_get_info_rsp(struct wcn36xx *wcn,
+						struct ieee80211_vif *vif)
+{
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+	struct wcn36xx_hal_gtk_offload_get_info_rsp_msg *rsp;
+	__be64 replay_ctr;
+
+	if (wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len))
+		return -EIO;
+
+	rsp = (struct wcn36xx_hal_gtk_offload_get_info_rsp_msg *)wcn->hal_buf;
+
+	if (rsp->bss_index != vif_priv->bss_index) {
+		wcn36xx_err("gtk_offload_info invalid response bss index %d\n",
+			    rsp->bss_index);
+		return -ENOENT;
+	}
+
+	replay_ctr = cpu_to_be64(le64_to_cpu(rsp->key_replay_counter));
+	if (vif_priv->rekey_data.replay_ctr != rsp->key_replay_counter) {
+		vif_priv->rekey_data.replay_ctr = rsp->key_replay_counter;
+		ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
+					   (void *)&replay_ctr, GFP_KERNEL);
+		 wcn36xx_dbg(WCN36XX_DBG_HAL,
+			     "GTK replay counter increment %llu\n",
+			     rsp->key_replay_counter);
+	}
+
+	wcn36xx_dbg(WCN36XX_DBG_HAL,
+		    "gtk offload info status %d last_rekey_status %d "
+		    "replay_counter %llu total_rekey_count %d gtk_rekey_count %d "
+		    "igtk_rekey_count %d bss_index %d\n",
+		    rsp->status, rsp->last_rekey_status,
+		    rsp->key_replay_counter, rsp->total_rekey_count,
+		    rsp->gtk_rekey_count, rsp->igtk_rekey_count,
+		    rsp->bss_index);
+
+	return 0;
+}
+
+int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
+				     struct ieee80211_vif *vif)
+{
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+	struct wcn36xx_hal_gtk_offload_get_info_req_msg msg_body;
+	int ret;
+
+	mutex_lock(&wcn->hal_mutex);
+
+	INIT_HAL_MSG(msg_body, WCN36XX_HAL_GTK_OFFLOAD_GETINFO_REQ);
+
+	msg_body.bss_index = vif_priv->bss_index;
+
+	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+	ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+	if (ret) {
+		wcn36xx_err("Sending gtk_offload_get_info failed\n");
+		goto out;
+	}
+	ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+	if (ret) {
+		wcn36xx_err("gtk_offload_get_info failed err=%d\n", ret);
+		goto out;
+	}
+	ret = wcn36xx_smd_gtk_offload_get_info_rsp(wcn, vif);
+out:
+	mutex_unlock(&wcn->hal_mutex);
+	return ret;
+}
+
 int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 			    void *buf, int len, void *priv, u32 addr)
 {
@@ -2943,6 +3014,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 	case WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP:
 	case WCN36XX_HAL_HOST_OFFLOAD_RSP:
 	case WCN36XX_HAL_GTK_OFFLOAD_RSP:
+	case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP:
 		memcpy(wcn->hal_buf, buf, len);
 		wcn->hal_rsp_len = len;
 		complete(&wcn->hal_rsp_compl);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index cdf4231efe26..90c7faea0ef6 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -156,4 +156,7 @@ int wcn36xx_smd_ipv6_ns_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 			    bool enable);
 
+int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
+				     struct ieee80211_vif *vif);
+
 #endif	/* _SMD_H_ */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 10/12] wcn36xx: Add Host suspend indication support
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (8 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 09/12] wcn36xx: Add GTK offload info to WoWLAN resume Bryan O'Donoghue
@ 2021-06-01 15:09 ` Bryan O'Donoghue
  2021-06-01 15:10 ` [PATCH v5 11/12] wcn36xx: Add host resume request support Bryan O'Donoghue
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:09 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

In order to activate ipv4 ARP offload, ipv6 NS offload and firmware GTK
offload we need to send a unidirectional indication from host to wcn
indicating a transition to suspend.

Once done, firmware will respond to ARP broadcasts, ipv6 NS lookups and
perform GTK rekeys without waking the host.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c |  3 +++
 drivers/net/wireless/ath/wcn36xx/smd.c  | 19 +++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h  |  2 ++
 3 files changed, 24 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 8e5d8326d551..e4d5e4d597f9 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1125,6 +1125,9 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 		if (ret)
 			goto out;
 		ret = wcn36xx_smd_set_power_params(wcn, true);
+		if (ret)
+			goto out;
+		ret = wcn36xx_smd_wlan_host_suspend_ind(wcn);
 	}
 out:
 	mutex_unlock(&wcn->conf_mutex);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index e249971c4ef7..302877d23ecf 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2964,6 +2964,25 @@ int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
 	return ret;
 }
 
+int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn)
+{
+	struct wcn36xx_hal_wlan_host_suspend_ind_msg msg_body;
+	int ret;
+
+	mutex_lock(&wcn->hal_mutex);
+
+	INIT_HAL_MSG(msg_body, WCN36XX_HAL_HOST_SUSPEND_IND);
+	msg_body.configured_mcst_bcst_filter_setting = 0;
+	msg_body.active_session_count = 1;
+	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+	ret = rpmsg_send(wcn->smd_channel, wcn->hal_buf, msg_body.header.len);
+
+	mutex_unlock(&wcn->hal_mutex);
+
+	return ret;
+}
+
 int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 			    void *buf, int len, void *priv, u32 addr)
 {
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 90c7faea0ef6..2909facdb100 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -159,4 +159,6 @@ int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
 				     struct ieee80211_vif *vif);
 
+int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn);
+
 #endif	/* _SMD_H_ */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 11/12] wcn36xx: Add host resume request support
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (9 preceding siblings ...)
  2021-06-01 15:09 ` [PATCH v5 10/12] wcn36xx: Add Host suspend indication support Bryan O'Donoghue
@ 2021-06-01 15:10 ` Bryan O'Donoghue
  2021-06-01 15:10 ` [PATCH v5 12/12] wcn36xx: Enable WOWLAN flags Bryan O'Donoghue
  2021-06-01 18:16 ` [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Loic Poulain
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:10 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

This commit is the corresponding resume() path request to the firmware when
resuming. Unlike the suspend() version which is a unidirectional
indication, the resume version is a standard request/response.

Once the resume() request completes ipv4 ARP, ipv6 NS and GTK rekey offload
stop working and can subsequently be rolled back.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c |  1 +
 drivers/net/wireless/ath/wcn36xx/smd.c  | 35 +++++++++++++++++++++++++
 drivers/net/wireless/ath/wcn36xx/smd.h  |  2 ++
 3 files changed, 38 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index e4d5e4d597f9..c697b9f3633a 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1144,6 +1144,7 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
 	mutex_lock(&wcn->conf_mutex);
 	vif = wcn36xx_get_first_assoc_vif(wcn);
 	if (vif) {
+		wcn36xx_smd_host_resume(wcn);
 		wcn36xx_smd_set_power_params(wcn, false);
 		wcn36xx_smd_gtk_offload_get_info(wcn, vif);
 		wcn36xx_smd_gtk_offload(wcn, vif, false);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 302877d23ecf..de0f630a82be 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2983,6 +2983,40 @@ int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn)
 	return ret;
 }
 
+int wcn36xx_smd_host_resume(struct wcn36xx *wcn)
+{
+	struct wcn36xx_hal_wlan_host_resume_req_msg msg_body;
+	struct wcn36xx_hal_host_resume_rsp_msg *rsp;
+	int ret;
+
+	mutex_lock(&wcn->hal_mutex);
+
+	INIT_HAL_MSG(msg_body, WCN36XX_HAL_HOST_RESUME_REQ);
+	msg_body.configured_mcst_bcst_filter_setting = 0;
+
+	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
+
+	ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
+	if (ret) {
+		wcn36xx_err("Sending wlan_host_resume failed\n");
+		goto out;
+	}
+	ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+	if (ret) {
+		wcn36xx_err("wlan_host_resume err=%d\n", ret);
+		goto out;
+	}
+
+	rsp = (struct wcn36xx_hal_host_resume_rsp_msg *)wcn->hal_buf;
+	if (rsp->status)
+		wcn36xx_warn("wlan_host_resume status=%d\n", rsp->status);
+
+out:
+	mutex_unlock(&wcn->hal_mutex);
+
+	return ret;
+}
+
 int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 			    void *buf, int len, void *priv, u32 addr)
 {
@@ -3034,6 +3068,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
 	case WCN36XX_HAL_HOST_OFFLOAD_RSP:
 	case WCN36XX_HAL_GTK_OFFLOAD_RSP:
 	case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP:
+	case WCN36XX_HAL_HOST_RESUME_RSP:
 		memcpy(wcn->hal_buf, buf, len);
 		wcn->hal_rsp_len = len;
 		complete(&wcn->hal_rsp_compl);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 2909facdb100..d8bded03945d 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -161,4 +161,6 @@ int wcn36xx_smd_gtk_offload_get_info(struct wcn36xx *wcn,
 
 int wcn36xx_smd_wlan_host_suspend_ind(struct wcn36xx *wcn);
 
+int wcn36xx_smd_host_resume(struct wcn36xx *wcn);
+
 #endif	/* _SMD_H_ */
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 12/12] wcn36xx: Enable WOWLAN flags
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (10 preceding siblings ...)
  2021-06-01 15:10 ` [PATCH v5 11/12] wcn36xx: Add host resume request support Bryan O'Donoghue
@ 2021-06-01 15:10 ` Bryan O'Donoghue
  2021-06-01 18:16 ` [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Loic Poulain
  12 siblings, 0 replies; 16+ messages in thread
From: Bryan O'Donoghue @ 2021-06-01 15:10 UTC (permalink / raw)
  To: kvalo, wcn36xx, linux-wireless
  Cc: bryan.odonoghue, shawn.guo, benl, loic.poulain, bjorn.andersson

Enable flags for

- Magic packet
- GTK rekey

Previous patches implemented the necessary code to switch these two on.
Standalone magic packet absent GTK rekey is pretty useless, so it makes
sense to flag both at once.

Once done it is possible for wcn36xx firmware to

1. Respond to ipv4 and ipv6 ARP/NS lookup requests
2. Bring the system out of suspend when a magic packet is received.
   Magic in our case is a simple ipv4 or ipv6 unicast.
3. GTK rekey whilst in suspend
   Once we wake from suspend the GTK will be updated as necessary

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Benjamin Li <benl@squareup.com>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index c697b9f3633a..3a4e383b3a6c 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -173,7 +173,9 @@ static struct ieee80211_supported_band wcn_band_5ghz = {
 #ifdef CONFIG_PM
 
 static const struct wiphy_wowlan_support wowlan_support = {
-	.flags = WIPHY_WOWLAN_ANY
+	.flags = WIPHY_WOWLAN_ANY	|
+		 WIPHY_WOWLAN_MAGIC_PKT	|
+		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY
 };
 
 #endif
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan
  2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
                   ` (11 preceding siblings ...)
  2021-06-01 15:10 ` [PATCH v5 12/12] wcn36xx: Enable WOWLAN flags Bryan O'Donoghue
@ 2021-06-01 18:16 ` Loic Poulain
  12 siblings, 0 replies; 16+ messages in thread
From: Loic Poulain @ 2021-06-01 18:16 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: Kalle Valo, wcn36xx, linux-wireless, Shawn Guo, Benjamin Li,
	Bjorn Andersson

On Tue, 1 Jun 2021 at 17:08, Bryan O'Donoghue
<bryan.odonoghue@linaro.org> wrote:
>
> In both cases using Wireshark we see the target system receive an ARP or
> NS6 lookup and respond, followed by the host sending a ping or ping6 and
> the target system coming out of suspend.
>
> Similarly watching GTK keying on the AP when the device is in suspend, we
> see the firmware successfully rekey and when we resume, the host picking up
> the rekey material with persistence of the WiFi link during suspend/resume.
>
> commit 5336fad96e8f ("wcn36xx: Enable firmware offloaded keepalive")
> ensures that the link is kept alive in suspend, this additional set gives
> the ability to
>
> - Resolve ARP/NS6 lookups without waking the system
> - Rekeying in suspend
> - Suspending and resuming based on received datagram
>
> https://git.linaro.org/people/bryan.odonoghue/kernel.git/log/?h=ath.master-wcn36xx-fw-offload-suspend-resume
>
> Bryan O'Donoghue (12):
>   wcn36xx: Return result of set_power_params in suspend
>   wcn36xx: Run suspend for the first ieee80211_vif
>   wcn36xx: Add ipv4 ARP offload support in suspend
>   wcn36xx: Do not flush indication queue on suspend/resume
>   wcn36xx: Add ipv6 address tracking
>   wcn36xx: Add ipv6 namespace offload in suspend
>   wcn36xx: Add set_rekey_data callback
>   wcn36xx: Add GTK offload to WoWLAN path
>   wcn36xx: Add GTK offload info to WoWLAN resume
>   wcn36xx: Add Host suspend indication support
>   wcn36xx: Add host resume request support
>   wcn36xx: Enable WOWLAN flags
>
>  drivers/net/wireless/ath/wcn36xx/hal.h     |  20 +-
>  drivers/net/wireless/ath/wcn36xx/main.c    | 110 ++++++++-
>  drivers/net/wireless/ath/wcn36xx/smd.c     | 265 +++++++++++++++++++++
>  drivers/net/wireless/ath/wcn36xx/smd.h     |  17 ++
>  drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  14 ++
>  5 files changed, 412 insertions(+), 14 deletions(-)

Reviewed-by: Loic Poulain <loic.poulain@linaro.org>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 08/12] wcn36xx: Add GTK offload to WoWLAN path
  2021-06-01 15:09 ` [PATCH v5 08/12] wcn36xx: Add GTK offload to WoWLAN path Bryan O'Donoghue
@ 2021-06-04  4:57   ` kernel test robot
  0 siblings, 0 replies; 16+ messages in thread
From: kernel test robot @ 2021-06-04  4:57 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3511 bytes --]

Hi Bryan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on wireless-drivers-next/master]
[also build test WARNING on wireless-drivers/master ath6kl/ath-next v5.13-rc4 next-20210603]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Bryan-O-Donoghue/wcn36xx-Enable-downstream-consistent-Wake-on-Lan/20210601-231011
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: x86_64-randconfig-s022-20210604 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-341-g8af24329-dirty
        # https://github.com/0day-ci/linux/commit/3fc5c2f97f5bdc763f508bbb239b5eedc324be42
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bryan-O-Donoghue/wcn36xx-Enable-downstream-consistent-Wake-on-Lan/20210601-231011
        git checkout 3fc5c2f97f5bdc763f508bbb239b5eedc324be42
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/net/wireless/ath/wcn36xx/smd.c:2873:45: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned long long [addressable] [assigned] [usertype] key_replay_counter @@     got restricted __le64 [usertype] replay_ctr @@
   drivers/net/wireless/ath/wcn36xx/smd.c:2873:45: sparse:     expected unsigned long long [addressable] [assigned] [usertype] key_replay_counter
   drivers/net/wireless/ath/wcn36xx/smd.c:2873:45: sparse:     got restricted __le64 [usertype] replay_ctr

vim +2873 drivers/net/wireless/ath/wcn36xx/smd.c

  2858	
  2859	int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
  2860				    bool enable)
  2861	{
  2862		struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
  2863		struct wcn36xx_hal_gtk_offload_req_msg msg_body;
  2864		int ret;
  2865	
  2866		mutex_lock(&wcn->hal_mutex);
  2867	
  2868		INIT_HAL_MSG(msg_body, WCN36XX_HAL_GTK_OFFLOAD_REQ);
  2869	
  2870		if (enable) {
  2871			memcpy(&msg_body.kek, vif_priv->rekey_data.kek, NL80211_KEK_LEN);
  2872			memcpy(&msg_body.kck, vif_priv->rekey_data.kck, NL80211_KCK_LEN);
> 2873			msg_body.key_replay_counter = vif_priv->rekey_data.replay_ctr;
  2874			msg_body.bss_index = vif_priv->bss_index;
  2875		} else {
  2876			msg_body.flags = WCN36XX_HAL_GTK_OFFLOAD_FLAGS_DISABLE;
  2877		}
  2878	
  2879		PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
  2880	
  2881		ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
  2882		if (ret) {
  2883			wcn36xx_err("Sending host_offload_arp failed\n");
  2884			goto out;
  2885		}
  2886		ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
  2887		if (ret) {
  2888			wcn36xx_err("host_offload_arp failed err=%d\n", ret);
  2889			goto out;
  2890		}
  2891	out:
  2892		mutex_unlock(&wcn->hal_mutex);
  2893		return ret;
  2894	}
  2895	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 34715 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 09/12] wcn36xx: Add GTK offload info to WoWLAN resume
  2021-06-01 15:09 ` [PATCH v5 09/12] wcn36xx: Add GTK offload info to WoWLAN resume Bryan O'Donoghue
@ 2021-06-04  6:13   ` kernel test robot
  0 siblings, 0 replies; 16+ messages in thread
From: kernel test robot @ 2021-06-04  6:13 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5846 bytes --]

Hi Bryan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on wireless-drivers-next/master]
[also build test WARNING on wireless-drivers/master ath6kl/ath-next v5.13-rc4 next-20210603]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Bryan-O-Donoghue/wcn36xx-Enable-downstream-consistent-Wake-on-Lan/20210601-231011
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: x86_64-randconfig-s022-20210604 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-341-g8af24329-dirty
        # https://github.com/0day-ci/linux/commit/8854b48adc6181a19c1410154f649a2bbb463a9d
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Bryan-O-Donoghue/wcn36xx-Enable-downstream-consistent-Wake-on-Lan/20210601-231011
        git checkout 8854b48adc6181a19c1410154f649a2bbb463a9d
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
   drivers/net/wireless/ath/wcn36xx/smd.c:2873:45: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned long long [addressable] [assigned] [usertype] key_replay_counter @@     got restricted __le64 [usertype] replay_ctr @@
   drivers/net/wireless/ath/wcn36xx/smd.c:2873:45: sparse:     expected unsigned long long [addressable] [assigned] [usertype] key_replay_counter
   drivers/net/wireless/ath/wcn36xx/smd.c:2873:45: sparse:     got restricted __le64 [usertype] replay_ctr
>> drivers/net/wireless/ath/wcn36xx/smd.c:2914:22: sparse: sparse: cast to restricted __le64
>> drivers/net/wireless/ath/wcn36xx/smd.c:2915:33: sparse: sparse: restricted __le64 degrades to integer
>> drivers/net/wireless/ath/wcn36xx/smd.c:2916:49: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le64 [usertype] replay_ctr @@     got unsigned long long [usertype] key_replay_counter @@
   drivers/net/wireless/ath/wcn36xx/smd.c:2916:49: sparse:     expected restricted __le64 [usertype] replay_ctr
   drivers/net/wireless/ath/wcn36xx/smd.c:2916:49: sparse:     got unsigned long long [usertype] key_replay_counter

vim +2914 drivers/net/wireless/ath/wcn36xx/smd.c

  2858	
  2859	int wcn36xx_smd_gtk_offload(struct wcn36xx *wcn, struct ieee80211_vif *vif,
  2860				    bool enable)
  2861	{
  2862		struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
  2863		struct wcn36xx_hal_gtk_offload_req_msg msg_body;
  2864		int ret;
  2865	
  2866		mutex_lock(&wcn->hal_mutex);
  2867	
  2868		INIT_HAL_MSG(msg_body, WCN36XX_HAL_GTK_OFFLOAD_REQ);
  2869	
  2870		if (enable) {
  2871			memcpy(&msg_body.kek, vif_priv->rekey_data.kek, NL80211_KEK_LEN);
  2872			memcpy(&msg_body.kck, vif_priv->rekey_data.kck, NL80211_KCK_LEN);
> 2873			msg_body.key_replay_counter = vif_priv->rekey_data.replay_ctr;
  2874			msg_body.bss_index = vif_priv->bss_index;
  2875		} else {
  2876			msg_body.flags = WCN36XX_HAL_GTK_OFFLOAD_FLAGS_DISABLE;
  2877		}
  2878	
  2879		PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
  2880	
  2881		ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
  2882		if (ret) {
  2883			wcn36xx_err("Sending host_offload_arp failed\n");
  2884			goto out;
  2885		}
  2886		ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
  2887		if (ret) {
  2888			wcn36xx_err("host_offload_arp failed err=%d\n", ret);
  2889			goto out;
  2890		}
  2891	out:
  2892		mutex_unlock(&wcn->hal_mutex);
  2893		return ret;
  2894	}
  2895	
  2896	static int wcn36xx_smd_gtk_offload_get_info_rsp(struct wcn36xx *wcn,
  2897							struct ieee80211_vif *vif)
  2898	{
  2899		struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
  2900		struct wcn36xx_hal_gtk_offload_get_info_rsp_msg *rsp;
  2901		__be64 replay_ctr;
  2902	
  2903		if (wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len))
  2904			return -EIO;
  2905	
  2906		rsp = (struct wcn36xx_hal_gtk_offload_get_info_rsp_msg *)wcn->hal_buf;
  2907	
  2908		if (rsp->bss_index != vif_priv->bss_index) {
  2909			wcn36xx_err("gtk_offload_info invalid response bss index %d\n",
  2910				    rsp->bss_index);
  2911			return -ENOENT;
  2912		}
  2913	
> 2914		replay_ctr = cpu_to_be64(le64_to_cpu(rsp->key_replay_counter));
> 2915		if (vif_priv->rekey_data.replay_ctr != rsp->key_replay_counter) {
> 2916			vif_priv->rekey_data.replay_ctr = rsp->key_replay_counter;
  2917			ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
  2918						   (void *)&replay_ctr, GFP_KERNEL);
  2919			 wcn36xx_dbg(WCN36XX_DBG_HAL,
  2920				     "GTK replay counter increment %llu\n",
  2921				     rsp->key_replay_counter);
  2922		}
  2923	
  2924		wcn36xx_dbg(WCN36XX_DBG_HAL,
  2925			    "gtk offload info status %d last_rekey_status %d "
  2926			    "replay_counter %llu total_rekey_count %d gtk_rekey_count %d "
  2927			    "igtk_rekey_count %d bss_index %d\n",
  2928			    rsp->status, rsp->last_rekey_status,
  2929			    rsp->key_replay_counter, rsp->total_rekey_count,
  2930			    rsp->gtk_rekey_count, rsp->igtk_rekey_count,
  2931			    rsp->bss_index);
  2932	
  2933		return 0;
  2934	}
  2935	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 34715 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-06-04  6:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-01 15:09 [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 01/12] wcn36xx: Return result of set_power_params in suspend Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 02/12] wcn36xx: Run suspend for the first ieee80211_vif Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 03/12] wcn36xx: Add ipv4 ARP offload support in suspend Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 04/12] wcn36xx: Do not flush indication queue on suspend/resume Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 05/12] wcn36xx: Add ipv6 address tracking Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 06/12] wcn36xx: Add ipv6 namespace offload in suspend Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 07/12] wcn36xx: Add set_rekey_data callback Bryan O'Donoghue
2021-06-01 15:09 ` [PATCH v5 08/12] wcn36xx: Add GTK offload to WoWLAN path Bryan O'Donoghue
2021-06-04  4:57   ` kernel test robot
2021-06-01 15:09 ` [PATCH v5 09/12] wcn36xx: Add GTK offload info to WoWLAN resume Bryan O'Donoghue
2021-06-04  6:13   ` kernel test robot
2021-06-01 15:09 ` [PATCH v5 10/12] wcn36xx: Add Host suspend indication support Bryan O'Donoghue
2021-06-01 15:10 ` [PATCH v5 11/12] wcn36xx: Add host resume request support Bryan O'Donoghue
2021-06-01 15:10 ` [PATCH v5 12/12] wcn36xx: Enable WOWLAN flags Bryan O'Donoghue
2021-06-01 18:16 ` [PATCH v5 00/12] wcn36xx: Enable downstream consistent Wake on Lan Loic Poulain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.