1 /* 2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 3 * 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 19 int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) 20 { 21 int rc = 0; 22 struct wireless_dev *wdev = wil->wdev; 23 24 wil_dbg_pm(wil, "%s(%s)\n", __func__, 25 is_runtime ? "runtime" : "system"); 26 27 switch (wdev->iftype) { 28 case NL80211_IFTYPE_MONITOR: 29 case NL80211_IFTYPE_STATION: 30 case NL80211_IFTYPE_P2P_CLIENT: 31 break; 32 /* AP-like interface - can't suspend */ 33 default: 34 wil_dbg_pm(wil, "AP-like interface\n"); 35 rc = -EBUSY; 36 break; 37 } 38 39 wil_dbg_pm(wil, "%s(%s) => %s (%d)\n", __func__, 40 is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc); 41 42 return rc; 43 } 44 45 int wil_suspend(struct wil6210_priv *wil, bool is_runtime) 46 { 47 int rc = 0; 48 struct net_device *ndev = wil_to_ndev(wil); 49 50 wil_dbg_pm(wil, "%s(%s)\n", __func__, 51 is_runtime ? "runtime" : "system"); 52 53 /* if netif up, hardware is alive, shut it down */ 54 if (ndev->flags & IFF_UP) { 55 rc = wil_down(wil); 56 if (rc) { 57 wil_err(wil, "wil_down : %d\n", rc); 58 goto out; 59 } 60 } 61 62 if (wil->platform_ops.suspend) 63 rc = wil->platform_ops.suspend(wil->platform_handle); 64 65 out: 66 wil_dbg_pm(wil, "%s(%s) => %d\n", __func__, 67 is_runtime ? "runtime" : "system", rc); 68 return rc; 69 } 70 71 int wil_resume(struct wil6210_priv *wil, bool is_runtime) 72 { 73 int rc = 0; 74 struct net_device *ndev = wil_to_ndev(wil); 75 76 wil_dbg_pm(wil, "%s(%s)\n", __func__, 77 is_runtime ? "runtime" : "system"); 78 79 if (wil->platform_ops.resume) { 80 rc = wil->platform_ops.resume(wil->platform_handle); 81 if (rc) { 82 wil_err(wil, "platform_ops.resume : %d\n", rc); 83 goto out; 84 } 85 } 86 87 /* if netif up, bring hardware up 88 * During open(), IFF_UP set after actual device method 89 * invocation. This prevent recursive call to wil_up() 90 */ 91 if (ndev->flags & IFF_UP) 92 rc = wil_up(wil); 93 94 out: 95 wil_dbg_pm(wil, "%s(%s) => %d\n", __func__, 96 is_runtime ? "runtime" : "system", rc); 97 return rc; 98 } 99