summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse2007-12-12 23:38:56 +0100
committerDavid S. Miller2008-01-29 00:07:03 +0100
commitab25ecaea5459f2206dbae25106cff67a24d309e (patch)
treec5f7917f257fc880c5cbe8037ab4b895899b47a9
parentlibertas: make worker thread not freezable (diff)
downloadkernel-qcow2-linux-ab25ecaea5459f2206dbae25106cff67a24d309e.tar.gz
kernel-qcow2-linux-ab25ecaea5459f2206dbae25106cff67a24d309e.tar.xz
kernel-qcow2-linux-ab25ecaea5459f2206dbae25106cff67a24d309e.zip
libertas: implement suspend and resume core methods
We (ab)use priv->fw_ready to stop the worker thread from sending more commands or data after the response to the HOST_SLEEP_ACTIVATE command comes in. And we set it from the callback function _directly_ to ensure that the worker thread sees it immediately; if we did it in lbs_suspend() after waking up, that might be too late. Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/libertas/cmd.h2
-rw-r--r--drivers/net/wireless/libertas/main.c47
2 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index e800295479ba..e44a0db50487 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -35,5 +35,7 @@ int lbs_mesh_config(struct lbs_private *priv, int enable);
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
uint8_t gpio, uint8_t gap);
+int lbs_suspend(struct lbs_private *priv);
+int lbs_resume(struct lbs_private *priv);
#endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index dd432ea61947..1ea119ed3d22 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -820,6 +820,53 @@ static int lbs_thread(void *data)
return 0;
}
+static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
+ struct cmd_header *cmd)
+{
+ lbs_deb_fw("HOST_SLEEP_ACTIVATE succeeded\n");
+
+ netif_device_detach(priv->dev);
+ if (priv->mesh_dev)
+ netif_device_detach(priv->mesh_dev);
+
+ priv->fw_ready = 0;
+ return 0;
+}
+
+
+int lbs_suspend(struct lbs_private *priv)
+{
+ struct cmd_header cmd;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
+ sizeof(cmd), lbs_suspend_callback, 0);
+ if (ret)
+ lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(lbs_suspend);
+
+int lbs_resume(struct lbs_private *priv)
+{
+ priv->fw_ready = 1;
+
+ /* Firmware doesn't seem to give us RX packets any more
+ until we send it some command. Might as well update */
+ lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+ 0, 0, NULL);
+
+ netif_device_attach(priv->dev);
+ if (priv->mesh_dev)
+ netif_device_attach(priv->mesh_dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lbs_resume);
+
/**
* @brief This function downloads firmware image, gets
* HW spec from firmware and set basic parameters to