blob: a0acb2d0cb7933e21f62c98d6b96a80cb51f9ef7 [file] [log] [blame]
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +03001/*
Lazar Alexei3190cc62017-02-23 14:34:14 +02002 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +03003 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "wil6210.h"
18
19int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
20{
21 int rc = 0;
22 struct wireless_dev *wdev = wil->wdev;
23
Lazar Alexei3190cc62017-02-23 14:34:14 +020024 wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system");
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030025
Maya Ereze34dc642016-05-16 22:23:34 +030026 if (!netif_running(wil_to_ndev(wil))) {
27 /* can always sleep when down */
28 wil_dbg_pm(wil, "Interface is down\n");
29 goto out;
30 }
31 if (test_bit(wil_status_resetting, wil->status)) {
32 wil_dbg_pm(wil, "Delay suspend when resetting\n");
33 rc = -EBUSY;
34 goto out;
35 }
36 if (wil->recovery_state != fw_recovery_idle) {
37 wil_dbg_pm(wil, "Delay suspend during recovery\n");
38 rc = -EBUSY;
39 goto out;
40 }
41
42 /* interface is running */
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030043 switch (wdev->iftype) {
44 case NL80211_IFTYPE_MONITOR:
45 case NL80211_IFTYPE_STATION:
46 case NL80211_IFTYPE_P2P_CLIENT:
Maya Ereze34dc642016-05-16 22:23:34 +030047 if (test_bit(wil_status_fwconnecting, wil->status)) {
48 wil_dbg_pm(wil, "Delay suspend when connecting\n");
49 rc = -EBUSY;
50 goto out;
51 }
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030052 break;
53 /* AP-like interface - can't suspend */
54 default:
55 wil_dbg_pm(wil, "AP-like interface\n");
56 rc = -EBUSY;
57 break;
58 }
59
Maya Ereze34dc642016-05-16 22:23:34 +030060out:
Lazar Alexei3190cc62017-02-23 14:34:14 +020061 wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n",
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030062 is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc);
63
64 return rc;
65}
66
67int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
68{
69 int rc = 0;
70 struct net_device *ndev = wil_to_ndev(wil);
71
Lazar Alexei3190cc62017-02-23 14:34:14 +020072 wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030073
74 /* if netif up, hardware is alive, shut it down */
75 if (ndev->flags & IFF_UP) {
76 rc = wil_down(wil);
77 if (rc) {
78 wil_err(wil, "wil_down : %d\n", rc);
79 goto out;
80 }
81 }
82
83 if (wil->platform_ops.suspend)
84 rc = wil->platform_ops.suspend(wil->platform_handle);
85
86out:
Lazar Alexei3190cc62017-02-23 14:34:14 +020087 wil_dbg_pm(wil, "suspend: %s => %d\n",
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030088 is_runtime ? "runtime" : "system", rc);
89 return rc;
90}
91
92int wil_resume(struct wil6210_priv *wil, bool is_runtime)
93{
94 int rc = 0;
95 struct net_device *ndev = wil_to_ndev(wil);
96
Lazar Alexei3190cc62017-02-23 14:34:14 +020097 wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +030098
99 if (wil->platform_ops.resume) {
100 rc = wil->platform_ops.resume(wil->platform_handle);
101 if (rc) {
102 wil_err(wil, "platform_ops.resume : %d\n", rc);
103 goto out;
104 }
105 }
106
107 /* if netif up, bring hardware up
108 * During open(), IFF_UP set after actual device method
109 * invocation. This prevent recursive call to wil_up()
110 */
111 if (ndev->flags & IFF_UP)
112 rc = wil_up(wil);
113
114out:
Lazar Alexei3190cc62017-02-23 14:34:14 +0200115 wil_dbg_pm(wil, "resume: %s => %d\n",
Vladimir Kondratiev93cb6792015-07-30 13:52:05 +0300116 is_runtime ? "runtime" : "system", rc);
117 return rc;
118}