wifi: wfx: allow to enable WoWLAN using NL80211
authorJérôme Pouiller <jerome.pouiller@silabs.com>
Tue, 4 Mar 2025 15:32:24 +0000 (16:32 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 7 Mar 2025 08:24:22 +0000 (09:24 +0100)
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>
Link: https://patch.msgid.link/20250304153224.39083-6-jerome.pouiller@silabs.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/silabs/wfx/bus.h
drivers/net/wireless/silabs/wfx/bus_sdio.c
drivers/net/wireless/silabs/wfx/bus_spi.c
drivers/net/wireless/silabs/wfx/main.c
drivers/net/wireless/silabs/wfx/sta.c
drivers/net/wireless/silabs/wfx/sta.h

index ccadfdd6873ced12693e2674f9d58b4c6e3ad6fd..79edaef20881abdac18129d52f9c0021268de4e2 100644 (file)
@@ -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;
index 27c5d7f534a4d109d46b9a56e0ad1733cbef08ed..ab0793b9908f4227a63dd63be8e46ac82e81e356 100644 (file)
@@ -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[] = {
index 20b9c016b40cd4c68d49ab2071d36b7d402c2c05..45ee19e1ecbf2cd9aaa973ef96c947ebd321e09f 100644 (file)
@@ -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)
index 55573d975cf91936a95ea08c6e4755c648e2dd98..a61128debbadcfc99dac9e4ee0e4bc04d7c2db93 100644 (file)
@@ -162,6 +162,7 @@ static const struct ieee80211_ops wfx_ops = {
 #ifdef CONFIG_PM
        .suspend                 = wfx_suspend,
        .resume                  = wfx_resume,
+       .set_wakeup              = wfx_set_wakeup,
 #endif
 };
 
index 9e06f8b8b90d99198d83aaf05e7ec92e27b5d090..e95b9ded17d9d7973841d27eec62a093dbfb5674 100644 (file)
@@ -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)
index 70ccc8cb7ec71926b740e70a418e915ef65f300b..8702eed5267f839e4dba413989aab04c0a2dbc8d 100644 (file)
@@ -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);