aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2010-05-19 06:24:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-02 16:13:06 -0400
commit66fceb69b72ff7e9cd8da2ca70033982d5376e0e (patch)
treeaa91d0d6c1c9e620a9718798fe925ebc3bab3eb8 /drivers/net/wireless/libertas
parenta7da74fc88bff6f82f8255f2def49907f82f4c61 (diff)
libertas: Added callback functions to support SDIO suspend/resume.
In suspend() host sleep is activated using already configured host sleep parameters through wol command, and in resume() host sleep is cancelled. Earlier priv->fw_ready flag used to reset and set in suspend and resume handler respectively. Since after suspend only host goes into sleep state and firmware is always ready, those changes in flag state are removed. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/cmd.c37
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c30
-rw-r--r--drivers/net/wireless/libertas/decl.h2
-rw-r--r--drivers/net/wireless/libertas/dev.h6
-rw-r--r--drivers/net/wireless/libertas/ethtool.c15
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c58
-rw-r--r--drivers/net/wireless/libertas/if_usb.c6
-rw-r--r--drivers/net/wireless/libertas/main.c79
8 files changed, 171 insertions, 62 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index cdb9b9650d73..0fa6b0e59ea5 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -70,6 +70,8 @@ static u8 is_command_allowed_in_ps(u16 cmd)
70 switch (cmd) { 70 switch (cmd) {
71 case CMD_802_11_RSSI: 71 case CMD_802_11_RSSI:
72 return 1; 72 return 1;
73 case CMD_802_11_HOST_SLEEP_CFG:
74 return 1;
73 default: 75 default:
74 break; 76 break;
75 } 77 }
@@ -185,6 +187,23 @@ out:
185 return ret; 187 return ret;
186} 188}
187 189
190static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
191 struct cmd_header *resp)
192{
193 lbs_deb_enter(LBS_DEB_CMD);
194 if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
195 priv->is_host_sleep_configured = 0;
196 if (priv->psstate == PS_STATE_FULL_POWER) {
197 priv->is_host_sleep_activated = 0;
198 wake_up_interruptible(&priv->host_sleep_q);
199 }
200 } else {
201 priv->is_host_sleep_configured = 1;
202 }
203 lbs_deb_leave(LBS_DEB_CMD);
204 return 0;
205}
206
188int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, 207int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
189 struct wol_config *p_wol_config) 208 struct wol_config *p_wol_config)
190{ 209{
@@ -202,12 +221,11 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
202 else 221 else
203 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE; 222 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
204 223
205 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config); 224 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
225 le16_to_cpu(cmd_config.hdr.size),
226 lbs_ret_host_sleep_cfg, 0);
206 if (!ret) { 227 if (!ret) {
207 if (criteria) { 228 if (p_wol_config)
208 lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
209 priv->wol_criteria = criteria;
210 } else
211 memcpy((uint8_t *) p_wol_config, 229 memcpy((uint8_t *) p_wol_config,
212 (uint8_t *)&cmd_config.wol_conf, 230 (uint8_t *)&cmd_config.wol_conf,
213 sizeof(struct wol_config)); 231 sizeof(struct wol_config));
@@ -712,6 +730,10 @@ static void lbs_queue_cmd(struct lbs_private *priv,
712 } 730 }
713 } 731 }
714 732
733 if (le16_to_cpu(cmdnode->cmdbuf->command) ==
734 CMD_802_11_WAKEUP_CONFIRM)
735 addtail = 0;
736
715 spin_lock_irqsave(&priv->driver_lock, flags); 737 spin_lock_irqsave(&priv->driver_lock, flags);
716 738
717 if (addtail) 739 if (addtail)
@@ -1353,6 +1375,11 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
1353 /* We don't get a response on the sleep-confirmation */ 1375 /* We don't get a response on the sleep-confirmation */
1354 priv->dnld_sent = DNLD_RES_RECEIVED; 1376 priv->dnld_sent = DNLD_RES_RECEIVED;
1355 1377
1378 if (priv->is_host_sleep_configured) {
1379 priv->is_host_sleep_activated = 1;
1380 wake_up_interruptible(&priv->host_sleep_q);
1381 }
1382
1356 /* If nothing to do, go back to sleep (?) */ 1383 /* If nothing to do, go back to sleep (?) */
1357 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) 1384 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1358 priv->psstate = PS_STATE_SLEEP; 1385 priv->psstate = PS_STATE_SLEEP;
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 88f7131d66e9..d6c306353640 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -17,6 +17,7 @@
17#include "dev.h" 17#include "dev.h"
18#include "assoc.h" 18#include "assoc.h"
19#include "wext.h" 19#include "wext.h"
20#include "cmd.h"
20 21
21/** 22/**
22 * @brief This function handles disconnect event. it 23 * @brief This function handles disconnect event. it
@@ -341,32 +342,10 @@ done:
341 return ret; 342 return ret;
342} 343}
343 344
344static int lbs_send_confirmwake(struct lbs_private *priv)
345{
346 struct cmd_header cmd;
347 int ret = 0;
348
349 lbs_deb_enter(LBS_DEB_HOST);
350
351 cmd.command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM);
352 cmd.size = cpu_to_le16(sizeof(cmd));
353 cmd.seqnum = cpu_to_le16(++priv->seqnum);
354 cmd.result = 0;
355
356 lbs_deb_hex(LBS_DEB_HOST, "wake confirm", (u8 *) &cmd,
357 sizeof(cmd));
358
359 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &cmd, sizeof(cmd));
360 if (ret)
361 lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n");
362
363 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
364 return ret;
365}
366
367int lbs_process_event(struct lbs_private *priv, u32 event) 345int lbs_process_event(struct lbs_private *priv, u32 event)
368{ 346{
369 int ret = 0; 347 int ret = 0;
348 struct cmd_header cmd;
370 349
371 lbs_deb_enter(LBS_DEB_CMD); 350 lbs_deb_enter(LBS_DEB_CMD);
372 351
@@ -410,7 +389,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
410 if (priv->reset_deep_sleep_wakeup) 389 if (priv->reset_deep_sleep_wakeup)
411 priv->reset_deep_sleep_wakeup(priv); 390 priv->reset_deep_sleep_wakeup(priv);
412 priv->is_deep_sleep = 0; 391 priv->is_deep_sleep = 0;
413 lbs_send_confirmwake(priv); 392 lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
393 sizeof(cmd));
394 priv->is_host_sleep_activated = 0;
395 wake_up_interruptible(&priv->host_sleep_q);
414 break; 396 break;
415 397
416 case MACREG_INT_CODE_DEEP_SLEEP_AWAKE: 398 case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 709ffcad22ad..61db8bc62b3c 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -38,7 +38,7 @@ int lbs_set_mac_address(struct net_device *dev, void *addr);
38void lbs_set_multicast_list(struct net_device *dev); 38void lbs_set_multicast_list(struct net_device *dev);
39 39
40int lbs_suspend(struct lbs_private *priv); 40int lbs_suspend(struct lbs_private *priv);
41void lbs_resume(struct lbs_private *priv); 41int lbs_resume(struct lbs_private *priv);
42 42
43void lbs_queue_event(struct lbs_private *priv, u32 event); 43void lbs_queue_event(struct lbs_private *priv, u32 event);
44void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx); 44void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index a54880e4ad2b..71c5ad46ebf6 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -75,6 +75,7 @@ struct lbs_private {
75 75
76 /* Deep sleep */ 76 /* Deep sleep */
77 int is_deep_sleep; 77 int is_deep_sleep;
78 int deep_sleep_required;
78 int is_auto_deep_sleep_enabled; 79 int is_auto_deep_sleep_enabled;
79 int wakeup_dev_required; 80 int wakeup_dev_required;
80 int is_activity_detected; 81 int is_activity_detected;
@@ -82,6 +83,11 @@ struct lbs_private {
82 wait_queue_head_t ds_awake_q; 83 wait_queue_head_t ds_awake_q;
83 struct timer_list auto_deepsleep_timer; 84 struct timer_list auto_deepsleep_timer;
84 85
86 /* Host sleep*/
87 int is_host_sleep_configured;
88 int is_host_sleep_activated;
89 wait_queue_head_t host_sleep_q;
90
85 /* Hardware access */ 91 /* Hardware access */
86 void *card; 92 void *card;
87 u8 fw_ready; 93 u8 fw_ready;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 3804a58d7f4e..6a36c9956fdc 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -91,23 +91,22 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
91 struct ethtool_wolinfo *wol) 91 struct ethtool_wolinfo *wol)
92{ 92{
93 struct lbs_private *priv = dev->ml_priv; 93 struct lbs_private *priv = dev->ml_priv;
94 uint32_t criteria = 0;
95 94
96 if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) 95 if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
97 return -EOPNOTSUPP; 96 return -EOPNOTSUPP;
98 97
98 priv->wol_criteria = 0;
99 if (wol->wolopts & WAKE_UCAST) 99 if (wol->wolopts & WAKE_UCAST)
100 criteria |= EHS_WAKE_ON_UNICAST_DATA; 100 priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA;
101 if (wol->wolopts & WAKE_MCAST) 101 if (wol->wolopts & WAKE_MCAST)
102 criteria |= EHS_WAKE_ON_MULTICAST_DATA; 102 priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA;
103 if (wol->wolopts & WAKE_BCAST) 103 if (wol->wolopts & WAKE_BCAST)
104 criteria |= EHS_WAKE_ON_BROADCAST_DATA; 104 priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA;
105 if (wol->wolopts & WAKE_PHY) 105 if (wol->wolopts & WAKE_PHY)
106 criteria |= EHS_WAKE_ON_MAC_EVENT; 106 priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT;
107 if (wol->wolopts == 0) 107 if (wol->wolopts == 0)
108 criteria |= EHS_REMOVE_WAKEUP; 108 priv->wol_criteria |= EHS_REMOVE_WAKEUP;
109 109 return 0;
110 return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
111} 110}
112 111
113const struct ethtool_ops lbs_ethtool_ops = { 112const struct ethtool_ops lbs_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 64dd345d30f5..6e71346a7550 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1182,11 +1182,69 @@ static void if_sdio_remove(struct sdio_func *func)
1182 lbs_deb_leave(LBS_DEB_SDIO); 1182 lbs_deb_leave(LBS_DEB_SDIO);
1183} 1183}
1184 1184
1185static int if_sdio_suspend(struct device *dev)
1186{
1187 struct sdio_func *func = dev_to_sdio_func(dev);
1188 int ret;
1189 struct if_sdio_card *card = sdio_get_drvdata(func);
1190
1191 mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
1192
1193 lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
1194 sdio_func_id(func), flags);
1195
1196 /* If we aren't being asked to wake on anything, we should bail out
1197 * and let the SD stack power down the card.
1198 */
1199 if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
1200 lbs_pr_info("Suspend without wake params -- "
1201 "powering down card.");
1202 return -ENOSYS;
1203 }
1204
1205 if (!(flags & MMC_PM_KEEP_POWER)) {
1206 lbs_pr_err("%s: cannot remain alive while host is suspended\n",
1207 sdio_func_id(func));
1208 return -ENOSYS;
1209 }
1210
1211 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1212 if (ret)
1213 return ret;
1214
1215 ret = lbs_suspend(card->priv);
1216 if (ret)
1217 return ret;
1218
1219 return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
1220}
1221
1222static int if_sdio_resume(struct device *dev)
1223{
1224 struct sdio_func *func = dev_to_sdio_func(dev);
1225 struct if_sdio_card *card = sdio_get_drvdata(func);
1226 int ret;
1227
1228 lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));
1229
1230 ret = lbs_resume(card->priv);
1231
1232 return ret;
1233}
1234
1235static const struct dev_pm_ops if_sdio_pm_ops = {
1236 .suspend = if_sdio_suspend,
1237 .resume = if_sdio_resume,
1238};
1239
1185static struct sdio_driver if_sdio_driver = { 1240static struct sdio_driver if_sdio_driver = {
1186 .name = "libertas_sdio", 1241 .name = "libertas_sdio",
1187 .id_table = if_sdio_ids, 1242 .id_table = if_sdio_ids,
1188 .probe = if_sdio_probe, 1243 .probe = if_sdio_probe,
1189 .remove = if_sdio_remove, 1244 .remove = if_sdio_remove,
1245 .drv = {
1246 .pm = &if_sdio_pm_ops,
1247 },
1190}; 1248};
1191 1249
1192/*******************************************************************/ 1250/*******************************************************************/
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index f41594c7ac16..a0cb265e5816 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -1043,6 +1043,12 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
1043 if (priv->psstate != PS_STATE_FULL_POWER) 1043 if (priv->psstate != PS_STATE_FULL_POWER)
1044 return -1; 1044 return -1;
1045 1045
1046 if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
1047 lbs_pr_info("Suspend attempt without "
1048 "configuring wake params!\n");
1049 return -ENOSYS;
1050 }
1051
1046 ret = lbs_suspend(priv); 1052 ret = lbs_suspend(priv);
1047 if (ret) 1053 if (ret)
1048 goto out; 1054 goto out;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index d9b8ee130c45..abfecc4814b4 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -625,16 +625,13 @@ static int lbs_thread(void *data)
625 return 0; 625 return 0;
626} 626}
627 627
628static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy, 628static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
629 struct cmd_header *cmd) 629 unsigned long dummy,
630 struct cmd_header *cmd)
630{ 631{
631 lbs_deb_enter(LBS_DEB_FW); 632 lbs_deb_enter(LBS_DEB_FW);
632 633 priv->is_host_sleep_activated = 1;
633 netif_device_detach(priv->dev); 634 wake_up_interruptible(&priv->host_sleep_q);
634 if (priv->mesh_dev)
635 netif_device_detach(priv->mesh_dev);
636
637 priv->fw_ready = 0;
638 lbs_deb_leave(LBS_DEB_FW); 635 lbs_deb_leave(LBS_DEB_FW);
639 return 0; 636 return 0;
640} 637}
@@ -646,39 +643,65 @@ int lbs_suspend(struct lbs_private *priv)
646 643
647 lbs_deb_enter(LBS_DEB_FW); 644 lbs_deb_enter(LBS_DEB_FW);
648 645
649 if (priv->wol_criteria == 0xffffffff) { 646 if (priv->is_deep_sleep) {
650 lbs_pr_info("Suspend attempt without configuring wake params!\n"); 647 ret = lbs_set_deep_sleep(priv, 0);
651 return -EINVAL; 648 if (ret) {
649 lbs_pr_err("deep sleep cancellation failed: %d\n", ret);
650 return ret;
651 }
652 priv->deep_sleep_required = 1;
652 } 653 }
653 654
654 memset(&cmd, 0, sizeof(cmd)); 655 memset(&cmd, 0, sizeof(cmd));
656 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
657 (struct wol_config *)NULL);
658 if (ret) {
659 lbs_pr_info("Host sleep configuration failed: %d\n", ret);
660 return ret;
661 }
662 if (priv->psstate == PS_STATE_FULL_POWER) {
663 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
664 sizeof(cmd), lbs_ret_host_sleep_activate, 0);
665 if (ret)
666 lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
667 }
655 668
656 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd, 669 if (!wait_event_interruptible_timeout(priv->host_sleep_q,
657 sizeof(cmd), lbs_suspend_callback, 0); 670 priv->is_host_sleep_activated, (10 * HZ))) {
658 if (ret) 671 lbs_pr_err("host_sleep_q: timer expired\n");
659 lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret); 672 ret = -1;
673 }
674 netif_device_detach(priv->dev);
675 if (priv->mesh_dev)
676 netif_device_detach(priv->mesh_dev);
660 677
661 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 678 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
662 return ret; 679 return ret;
663} 680}
664EXPORT_SYMBOL_GPL(lbs_suspend); 681EXPORT_SYMBOL_GPL(lbs_suspend);
665 682
666void lbs_resume(struct lbs_private *priv) 683int lbs_resume(struct lbs_private *priv)
667{ 684{
668 lbs_deb_enter(LBS_DEB_FW); 685 int ret;
686 uint32_t criteria = EHS_REMOVE_WAKEUP;
669 687
670 priv->fw_ready = 1; 688 lbs_deb_enter(LBS_DEB_FW);
671 689
672 /* Firmware doesn't seem to give us RX packets any more 690 ret = lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
673 until we send it some command. Might as well update */
674 lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
675 0, 0, NULL);
676 691
677 netif_device_attach(priv->dev); 692 netif_device_attach(priv->dev);
678 if (priv->mesh_dev) 693 if (priv->mesh_dev)
679 netif_device_attach(priv->mesh_dev); 694 netif_device_attach(priv->mesh_dev);
680 695
681 lbs_deb_leave(LBS_DEB_FW); 696 if (priv->deep_sleep_required) {
697 priv->deep_sleep_required = 0;
698 ret = lbs_set_deep_sleep(priv, 1);
699 if (ret)
700 lbs_pr_err("deep sleep activation failed: %d\n", ret);
701 }
702
703 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
704 return ret;
682} 705}
683EXPORT_SYMBOL_GPL(lbs_resume); 706EXPORT_SYMBOL_GPL(lbs_resume);
684 707
@@ -834,10 +857,13 @@ static int lbs_init_adapter(struct lbs_private *priv)
834 priv->psstate = PS_STATE_FULL_POWER; 857 priv->psstate = PS_STATE_FULL_POWER;
835 priv->is_deep_sleep = 0; 858 priv->is_deep_sleep = 0;
836 priv->is_auto_deep_sleep_enabled = 0; 859 priv->is_auto_deep_sleep_enabled = 0;
860 priv->deep_sleep_required = 0;
837 priv->wakeup_dev_required = 0; 861 priv->wakeup_dev_required = 0;
838 init_waitqueue_head(&priv->ds_awake_q); 862 init_waitqueue_head(&priv->ds_awake_q);
839 priv->authtype_auto = 1; 863 priv->authtype_auto = 1;
840 864 priv->is_host_sleep_configured = 0;
865 priv->is_host_sleep_activated = 0;
866 init_waitqueue_head(&priv->host_sleep_q);
841 mutex_init(&priv->lock); 867 mutex_init(&priv->lock);
842 868
843 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, 869 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
@@ -976,6 +1002,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
976 1002
977 priv->wol_criteria = 0xffffffff; 1003 priv->wol_criteria = 0xffffffff;
978 priv->wol_gpio = 0xff; 1004 priv->wol_gpio = 0xff;
1005 priv->wol_gap = 20;
979 1006
980 goto done; 1007 goto done;
981 1008
@@ -1031,6 +1058,10 @@ void lbs_remove_card(struct lbs_private *priv)
1031 wake_up_interruptible(&priv->ds_awake_q); 1058 wake_up_interruptible(&priv->ds_awake_q);
1032 } 1059 }
1033 1060
1061 priv->is_host_sleep_configured = 0;
1062 priv->is_host_sleep_activated = 0;
1063 wake_up_interruptible(&priv->host_sleep_q);
1064
1034 /* Stop the thread servicing the interrupts */ 1065 /* Stop the thread servicing the interrupts */
1035 priv->surpriseremoved = 1; 1066 priv->surpriseremoved = 1;
1036 kthread_stop(priv->main_thread); 1067 kthread_stop(priv->main_thread);