pm.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include <net/mac80211.h>
  2. #include <net/rtnetlink.h>
  3. #include "ieee80211_i.h"
  4. #include "led.h"
  5. int __ieee80211_suspend(struct ieee80211_hw *hw)
  6. {
  7. struct ieee80211_local *local = hw_to_local(hw);
  8. struct ieee80211_sub_if_data *sdata;
  9. struct ieee80211_if_init_conf conf;
  10. struct sta_info *sta;
  11. unsigned long flags;
  12. ieee80211_stop_queues_by_reason(hw,
  13. IEEE80211_QUEUE_STOP_REASON_SUSPEND);
  14. flush_workqueue(local->hw.workqueue);
  15. /* disable keys */
  16. list_for_each_entry(sdata, &local->interfaces, list)
  17. ieee80211_disable_keys(sdata);
  18. /* Tear down aggregation sessions */
  19. rcu_read_lock();
  20. if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
  21. list_for_each_entry_rcu(sta, &local->sta_list, list) {
  22. set_sta_flags(sta, WLAN_STA_SUSPEND);
  23. ieee80211_sta_tear_down_BA_sessions(sta);
  24. }
  25. }
  26. rcu_read_unlock();
  27. /* remove STAs */
  28. if (local->ops->sta_notify) {
  29. spin_lock_irqsave(&local->sta_lock, flags);
  30. list_for_each_entry(sta, &local->sta_list, list) {
  31. if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  32. sdata = container_of(sdata->bss,
  33. struct ieee80211_sub_if_data,
  34. u.ap);
  35. local->ops->sta_notify(hw, &sdata->vif,
  36. STA_NOTIFY_REMOVE, &sta->sta);
  37. }
  38. spin_unlock_irqrestore(&local->sta_lock, flags);
  39. }
  40. /* remove all interfaces */
  41. list_for_each_entry(sdata, &local->interfaces, list) {
  42. if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  43. sdata->vif.type != NL80211_IFTYPE_MONITOR &&
  44. netif_running(sdata->dev)) {
  45. conf.vif = &sdata->vif;
  46. conf.type = sdata->vif.type;
  47. conf.mac_addr = sdata->dev->dev_addr;
  48. local->ops->remove_interface(hw, &conf);
  49. }
  50. }
  51. /* flush again, in case driver queued work */
  52. flush_workqueue(local->hw.workqueue);
  53. /* stop hardware */
  54. if (local->open_count) {
  55. ieee80211_led_radio(local, false);
  56. local->ops->stop(hw);
  57. }
  58. return 0;
  59. }
  60. int __ieee80211_resume(struct ieee80211_hw *hw)
  61. {
  62. struct ieee80211_local *local = hw_to_local(hw);
  63. struct ieee80211_sub_if_data *sdata;
  64. struct ieee80211_if_init_conf conf;
  65. struct sta_info *sta;
  66. unsigned long flags;
  67. int res;
  68. /* restart hardware */
  69. if (local->open_count) {
  70. res = local->ops->start(hw);
  71. ieee80211_led_radio(local, hw->conf.radio_enabled);
  72. }
  73. /* add interfaces */
  74. list_for_each_entry(sdata, &local->interfaces, list) {
  75. if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
  76. sdata->vif.type != NL80211_IFTYPE_MONITOR &&
  77. netif_running(sdata->dev)) {
  78. conf.vif = &sdata->vif;
  79. conf.type = sdata->vif.type;
  80. conf.mac_addr = sdata->dev->dev_addr;
  81. res = local->ops->add_interface(hw, &conf);
  82. }
  83. }
  84. /* add STAs back */
  85. if (local->ops->sta_notify) {
  86. spin_lock_irqsave(&local->sta_lock, flags);
  87. list_for_each_entry(sta, &local->sta_list, list) {
  88. if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
  89. sdata = container_of(sdata->bss,
  90. struct ieee80211_sub_if_data,
  91. u.ap);
  92. local->ops->sta_notify(hw, &sdata->vif,
  93. STA_NOTIFY_ADD, &sta->sta);
  94. }
  95. spin_unlock_irqrestore(&local->sta_lock, flags);
  96. }
  97. /* Clear Suspend state so that ADDBA requests can be processed */
  98. rcu_read_lock();
  99. if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
  100. list_for_each_entry_rcu(sta, &local->sta_list, list) {
  101. clear_sta_flags(sta, WLAN_STA_SUSPEND);
  102. }
  103. }
  104. rcu_read_unlock();
  105. /* add back keys */
  106. list_for_each_entry(sdata, &local->interfaces, list)
  107. if (netif_running(sdata->dev))
  108. ieee80211_enable_keys(sdata);
  109. /* setup RTS threshold */
  110. if (local->ops->set_rts_threshold)
  111. local->ops->set_rts_threshold(hw, local->rts_threshold);
  112. /* reconfigure hardware */
  113. ieee80211_hw_config(local, ~0);
  114. netif_addr_lock_bh(local->mdev);
  115. ieee80211_configure_filter(local);
  116. netif_addr_unlock_bh(local->mdev);
  117. /* Finally also reconfigure all the BSS information */
  118. list_for_each_entry(sdata, &local->interfaces, list) {
  119. u32 changed = ~0;
  120. if (!netif_running(sdata->dev))
  121. continue;
  122. switch (sdata->vif.type) {
  123. case NL80211_IFTYPE_STATION:
  124. /* disable beacon change bits */
  125. changed &= ~IEEE80211_IFCC_BEACON;
  126. /* fall through */
  127. case NL80211_IFTYPE_ADHOC:
  128. case NL80211_IFTYPE_AP:
  129. case NL80211_IFTYPE_MESH_POINT:
  130. /*
  131. * Driver's config_interface can fail if rfkill is
  132. * enabled. Accommodate this return code.
  133. * FIXME: When mac80211 has knowledge of rfkill
  134. * state the code below can change back to:
  135. * WARN(ieee80211_if_config(sdata, changed));
  136. * ieee80211_bss_info_change_notify(sdata, ~0);
  137. */
  138. if (ieee80211_if_config(sdata, changed))
  139. printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
  140. sdata->dev->name);
  141. else
  142. ieee80211_bss_info_change_notify(sdata, ~0);
  143. break;
  144. case NL80211_IFTYPE_WDS:
  145. break;
  146. case NL80211_IFTYPE_AP_VLAN:
  147. case NL80211_IFTYPE_MONITOR:
  148. /* ignore virtual */
  149. break;
  150. case NL80211_IFTYPE_UNSPECIFIED:
  151. case __NL80211_IFTYPE_AFTER_LAST:
  152. WARN_ON(1);
  153. break;
  154. }
  155. }
  156. ieee80211_wake_queues_by_reason(hw,
  157. IEEE80211_QUEUE_STOP_REASON_SUSPEND);
  158. return 0;
  159. }