Search Linux Wireless

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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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 --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 83fd278e615e..17ba2c59e53d 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);
-- 
2.39.5





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux