diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-12-12 17:38:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:07:03 -0500 |
commit | ab25ecaea5459f2206dbae25106cff67a24d309e (patch) | |
tree | c5f7917f257fc880c5cbe8037ab4b895899b47a9 /drivers/net | |
parent | f3db2bb411512d1ebd6233b3985d98f4fe7ea8a8 (diff) |
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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 47 |
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); | |||
35 | 35 | ||
36 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, | 36 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, |
37 | uint8_t gpio, uint8_t gap); | 37 | uint8_t gpio, uint8_t gap); |
38 | int lbs_suspend(struct lbs_private *priv); | ||
39 | int lbs_resume(struct lbs_private *priv); | ||
38 | 40 | ||
39 | #endif /* _LBS_CMD_H */ | 41 | #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) | |||
820 | return 0; | 820 | return 0; |
821 | } | 821 | } |
822 | 822 | ||
823 | static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy, | ||
824 | struct cmd_header *cmd) | ||
825 | { | ||
826 | lbs_deb_fw("HOST_SLEEP_ACTIVATE succeeded\n"); | ||
827 | |||
828 | netif_device_detach(priv->dev); | ||
829 | if (priv->mesh_dev) | ||
830 | netif_device_detach(priv->mesh_dev); | ||
831 | |||
832 | priv->fw_ready = 0; | ||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | |||
837 | int lbs_suspend(struct lbs_private *priv) | ||
838 | { | ||
839 | struct cmd_header cmd; | ||
840 | int ret; | ||
841 | |||
842 | memset(&cmd, 0, sizeof(cmd)); | ||
843 | |||
844 | ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd, | ||
845 | sizeof(cmd), lbs_suspend_callback, 0); | ||
846 | if (ret) | ||
847 | lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret); | ||
848 | |||
849 | return ret; | ||
850 | } | ||
851 | EXPORT_SYMBOL_GPL(lbs_suspend); | ||
852 | |||
853 | int lbs_resume(struct lbs_private *priv) | ||
854 | { | ||
855 | priv->fw_ready = 1; | ||
856 | |||
857 | /* Firmware doesn't seem to give us RX packets any more | ||
858 | until we send it some command. Might as well update */ | ||
859 | lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, | ||
860 | 0, 0, NULL); | ||
861 | |||
862 | netif_device_attach(priv->dev); | ||
863 | if (priv->mesh_dev) | ||
864 | netif_device_attach(priv->mesh_dev); | ||
865 | |||
866 | return 0; | ||
867 | } | ||
868 | EXPORT_SYMBOL_GPL(lbs_resume); | ||
869 | |||
823 | /** | 870 | /** |
824 | * @brief This function downloads firmware image, gets | 871 | * @brief This function downloads firmware image, gets |
825 | * HW spec from firmware and set basic parameters to | 872 | * HW spec from firmware and set basic parameters to |