pm.c 2.6 KB

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