Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Copyright (c) 2014,2016 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
 19int 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	if (!netif_running(wil_to_ndev(wil))) {
 28		/* can always sleep when down */
 29		wil_dbg_pm(wil, "Interface is down\n");
 30		goto out;
 31	}
 32	if (test_bit(wil_status_resetting, wil->status)) {
 33		wil_dbg_pm(wil, "Delay suspend when resetting\n");
 34		rc = -EBUSY;
 35		goto out;
 36	}
 37	if (wil->recovery_state != fw_recovery_idle) {
 38		wil_dbg_pm(wil, "Delay suspend during recovery\n");
 39		rc = -EBUSY;
 40		goto out;
 41	}
 42
 43	/* interface is running */
 44	switch (wdev->iftype) {
 45	case NL80211_IFTYPE_MONITOR:
 46	case NL80211_IFTYPE_STATION:
 47	case NL80211_IFTYPE_P2P_CLIENT:
 48		if (test_bit(wil_status_fwconnecting, wil->status)) {
 49			wil_dbg_pm(wil, "Delay suspend when connecting\n");
 50			rc = -EBUSY;
 51			goto out;
 52		}
 53		break;
 54	/* AP-like interface - can't suspend */
 55	default:
 56		wil_dbg_pm(wil, "AP-like interface\n");
 57		rc = -EBUSY;
 58		break;
 59	}
 60
 61out:
 62	wil_dbg_pm(wil, "%s(%s) => %s (%d)\n", __func__,
 63		   is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc);
 64
 65	return rc;
 66}
 67
 68int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
 69{
 70	int rc = 0;
 71	struct net_device *ndev = wil_to_ndev(wil);
 72
 73	wil_dbg_pm(wil, "%s(%s)\n", __func__,
 74		   is_runtime ? "runtime" : "system");
 75
 76	/* if netif up, hardware is alive, shut it down */
 77	if (ndev->flags & IFF_UP) {
 78		rc = wil_down(wil);
 79		if (rc) {
 80			wil_err(wil, "wil_down : %d\n", rc);
 81			goto out;
 82		}
 83	}
 84
 85	if (wil->platform_ops.suspend)
 86		rc = wil->platform_ops.suspend(wil->platform_handle);
 87
 88out:
 89	wil_dbg_pm(wil, "%s(%s) => %d\n", __func__,
 90		   is_runtime ? "runtime" : "system", rc);
 91	return rc;
 92}
 93
 94int wil_resume(struct wil6210_priv *wil, bool is_runtime)
 95{
 96	int rc = 0;
 97	struct net_device *ndev = wil_to_ndev(wil);
 98
 99	wil_dbg_pm(wil, "%s(%s)\n", __func__,
100		   is_runtime ? "runtime" : "system");
101
102	if (wil->platform_ops.resume) {
103		rc = wil->platform_ops.resume(wil->platform_handle);
104		if (rc) {
105			wil_err(wil, "platform_ops.resume : %d\n", rc);
106			goto out;
107		}
108	}
109
110	/* if netif up, bring hardware up
111	 * During open(), IFF_UP set after actual device method
112	 * invocation. This prevent recursive call to wil_up()
113	 */
114	if (ndev->flags & IFF_UP)
115		rc = wil_up(wil);
116
117out:
118	wil_dbg_pm(wil, "%s(%s) => %d\n", __func__,
119		   is_runtime ? "runtime" : "system", rc);
120	return rc;
121}