diff mbox series

[v2,5/5] wifi: wfx: allow to enable WoWLAN using NL80211

Message ID 20250302144731.117409-6-jerome.pouiller@silabs.com (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series wfx: add support for WoWLAN on Silabs WF200 | expand

Checks

Context Check Description
jmberg/fixes_present success Fixes tag not required for -next series
jmberg/series_format warning Target tree name not specified in the subject
jmberg/tree_selection success Guessed tree name to be wireless-next
jmberg/ynl success Generated files up to date; no warnings/errors; no diff in generated;
jmberg/build_32bit success Errors and warnings before: 0 this patch: 0
jmberg/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
jmberg/build_clang success Errors and warnings before: 0 this patch: 0
jmberg/build_clang_rust success No Rust files in patch. Skipping build
jmberg/build_tools success No tools touched, skip
jmberg/check_selftest success No net selftest shell script
jmberg/checkpatch success total: 0 errors, 0 warnings, 0 checks, 83 lines checked
jmberg/deprecated_api success None detected
jmberg/header_inline success No static functions without inline keyword in header files
jmberg/kdoc success Errors and warnings before: 0 this patch: 0
jmberg/source_inline success Was 0 now: 0
jmberg/verify_fixes success No Fixes tag
jmberg/verify_signedoff success Signed-off-by tag matches author and committer

Commit Message

Jérôme Pouiller March 2, 2025, 2:47 p.m. UTC
It is possible to use nl80211 to request to the driver to do allow the
required bus configuration to wake-up the host.

This patch implements the required API for nl80211.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/net/wireless/silabs/wfx/bus.h      |  1 +
 drivers/net/wireless/silabs/wfx/bus_sdio.c |  8 ++++++++
 drivers/net/wireless/silabs/wfx/bus_spi.c  |  8 ++++++++
 drivers/net/wireless/silabs/wfx/main.c     |  1 +
 drivers/net/wireless/silabs/wfx/sta.c      | 10 ++++++++++
 drivers/net/wireless/silabs/wfx/sta.h      |  1 +
 6 files changed, 29 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/wireless/silabs/wfx/bus.h b/drivers/net/wireless/silabs/wfx/bus.h
index ccadfdd6873c..79edaef20881 100644
--- a/drivers/net/wireless/silabs/wfx/bus.h
+++ b/drivers/net/wireless/silabs/wfx/bus.h
@@ -28,6 +28,7 @@  struct wfx_hwbus_ops {
 	void (*lock)(void *bus_priv);
 	void (*unlock)(void *bus_priv);
 	size_t (*align_size)(void *bus_priv, size_t size);
+	void (*set_wakeup)(void *priv, bool enabled);
 };
 
 extern struct sdio_driver wfx_sdio_driver;
diff --git a/drivers/net/wireless/silabs/wfx/bus_sdio.c b/drivers/net/wireless/silabs/wfx/bus_sdio.c
index bd8e1ffb61bb..5540f2c66075 100644
--- a/drivers/net/wireless/silabs/wfx/bus_sdio.c
+++ b/drivers/net/wireless/silabs/wfx/bus_sdio.c
@@ -173,6 +173,13 @@  static size_t wfx_sdio_align_size(void *priv, size_t size)
 	return sdio_align_size(bus->func, size);
 }
 
+static void wfx_sdio_set_wakeup(void *priv, bool enabled)
+{
+	struct wfx_sdio_priv *bus = priv;
+
+	device_set_wakeup_enable(&bus->func->dev, enabled);
+}
+
 static const struct wfx_hwbus_ops wfx_sdio_hwbus_ops = {
 	.copy_from_io    = wfx_sdio_copy_from_io,
 	.copy_to_io      = wfx_sdio_copy_to_io,
@@ -181,6 +188,7 @@  static const struct wfx_hwbus_ops wfx_sdio_hwbus_ops = {
 	.lock            = wfx_sdio_lock,
 	.unlock          = wfx_sdio_unlock,
 	.align_size      = wfx_sdio_align_size,
+	.set_wakeup      = wfx_sdio_set_wakeup,
 };
 
 static const struct of_device_id wfx_sdio_of_match[] = {
diff --git a/drivers/net/wireless/silabs/wfx/bus_spi.c b/drivers/net/wireless/silabs/wfx/bus_spi.c
index 1d6bf3525f4e..257bc3cd1197 100644
--- a/drivers/net/wireless/silabs/wfx/bus_spi.c
+++ b/drivers/net/wireless/silabs/wfx/bus_spi.c
@@ -180,6 +180,13 @@  static size_t wfx_spi_align_size(void *priv, size_t size)
 	return ALIGN(size, 4);
 }
 
+static void wfx_spi_set_wakeup(void *priv, bool enabled)
+{
+	struct wfx_spi_priv *bus = priv;
+
+	device_set_wakeup_enable(&bus->func->dev, enabled);
+}
+
 static const struct wfx_hwbus_ops wfx_spi_hwbus_ops = {
 	.copy_from_io    = wfx_spi_copy_from_io,
 	.copy_to_io      = wfx_spi_copy_to_io,
@@ -188,6 +195,7 @@  static const struct wfx_hwbus_ops wfx_spi_hwbus_ops = {
 	.lock            = wfx_spi_lock,
 	.unlock          = wfx_spi_unlock,
 	.align_size      = wfx_spi_align_size,
+	.set_wakeup      = wfx_spi_set_wakeup,
 };
 
 static int wfx_spi_suspend(struct device *dev)
diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c
index 62586786a45c..bd0cf4d29e5a 100644
--- a/drivers/net/wireless/silabs/wfx/main.c
+++ b/drivers/net/wireless/silabs/wfx/main.c
@@ -160,6 +160,7 @@  static const struct ieee80211_ops wfx_ops = {
 #ifdef CONFIG_PM
 	.suspend                 = wfx_suspend,
 	.resume                  = wfx_resume,
+	.set_wakeup              = wfx_set_wakeup,
 #endif
 };
 
diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c
index 9e06f8b8b90d..e95b9ded17d9 100644
--- a/drivers/net/wireless/silabs/wfx/sta.c
+++ b/drivers/net/wireless/silabs/wfx/sta.c
@@ -10,6 +10,7 @@ 
 
 #include "sta.h"
 #include "wfx.h"
+#include "bus.h"
 #include "fwio.h"
 #include "bh.h"
 #include "key.h"
@@ -816,6 +817,15 @@  int wfx_resume(struct ieee80211_hw *hw)
 {
 	return 0;
 }
+
+void wfx_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+	struct wfx_dev *wdev = hw->priv;
+
+	if (enabled)
+		dev_info(wdev->dev, "support for WoWLAN is experimental\n");
+	wdev->hwbus_ops->set_wakeup(wdev->hwbus_priv, enabled);
+}
 #endif
 
 int wfx_start(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/silabs/wfx/sta.h b/drivers/net/wireless/silabs/wfx/sta.h
index 70ccc8cb7ec7..8702eed5267f 100644
--- a/drivers/net/wireless/silabs/wfx/sta.h
+++ b/drivers/net/wireless/silabs/wfx/sta.h
@@ -58,6 +58,7 @@  void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif
 			      struct ieee80211_chanctx_conf *conf);
 int wfx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
 int wfx_resume(struct ieee80211_hw *hw);
+void wfx_set_wakeup(struct ieee80211_hw *hw, bool enabled);
 
 /* Hardware API Callbacks */
 void wfx_cooling_timeout_work(struct work_struct *work);