diff options
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/decl.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/ethtool.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 58 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 79 |
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 | ||
190 | static 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 | |||
188 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, | 207 | int 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 | ||
344 | static 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 | |||
367 | int lbs_process_event(struct lbs_private *priv, u32 event) | 345 | int 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); | |||
38 | void lbs_set_multicast_list(struct net_device *dev); | 38 | void lbs_set_multicast_list(struct net_device *dev); |
39 | 39 | ||
40 | int lbs_suspend(struct lbs_private *priv); | 40 | int lbs_suspend(struct lbs_private *priv); |
41 | void lbs_resume(struct lbs_private *priv); | 41 | int lbs_resume(struct lbs_private *priv); |
42 | 42 | ||
43 | void lbs_queue_event(struct lbs_private *priv, u32 event); | 43 | void lbs_queue_event(struct lbs_private *priv, u32 event); |
44 | void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx); | 44 | void 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 | ||
113 | const struct ethtool_ops lbs_ethtool_ops = { | 112 | const 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 | ||
1185 | static 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 | |||
1222 | static 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 | |||
1235 | static const struct dev_pm_ops if_sdio_pm_ops = { | ||
1236 | .suspend = if_sdio_suspend, | ||
1237 | .resume = if_sdio_resume, | ||
1238 | }; | ||
1239 | |||
1185 | static struct sdio_driver if_sdio_driver = { | 1240 | static 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 | ||
628 | static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy, | 628 | static 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 | } |
664 | EXPORT_SYMBOL_GPL(lbs_suspend); | 681 | EXPORT_SYMBOL_GPL(lbs_suspend); |
665 | 682 | ||
666 | void lbs_resume(struct lbs_private *priv) | 683 | int 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 | } |
683 | EXPORT_SYMBOL_GPL(lbs_resume); | 706 | EXPORT_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); |