1 #include <net/mac80211.h>
2 #include <net/rtnetlink.h>
4 #include "ieee80211_i.h"
5 #include "driver-ops.h"
8 int __ieee80211_suspend(struct ieee80211_hw
*hw
)
10 struct ieee80211_local
*local
= hw_to_local(hw
);
11 struct ieee80211_sub_if_data
*sdata
;
12 struct ieee80211_if_init_conf conf
;
16 ieee80211_stop_queues_by_reason(hw
,
17 IEEE80211_QUEUE_STOP_REASON_SUSPEND
);
19 flush_workqueue(local
->hw
.workqueue
);
22 list_for_each_entry(sdata
, &local
->interfaces
, list
)
23 ieee80211_disable_keys(sdata
);
25 /* Tear down aggregation sessions */
29 if (hw
->flags
& IEEE80211_HW_AMPDU_AGGREGATION
) {
30 list_for_each_entry_rcu(sta
, &local
->sta_list
, list
) {
31 set_sta_flags(sta
, WLAN_STA_SUSPEND
);
32 ieee80211_sta_tear_down_BA_sessions(sta
);
39 if (local
->ops
->sta_notify
) {
40 spin_lock_irqsave(&local
->sta_lock
, flags
);
41 list_for_each_entry(sta
, &local
->sta_list
, list
) {
42 if (sdata
->vif
.type
== NL80211_IFTYPE_AP_VLAN
)
43 sdata
= container_of(sdata
->bss
,
44 struct ieee80211_sub_if_data
,
47 drv_sta_notify(local
, &sdata
->vif
, STA_NOTIFY_REMOVE
,
50 spin_unlock_irqrestore(&local
->sta_lock
, flags
);
53 /* remove all interfaces */
54 list_for_each_entry(sdata
, &local
->interfaces
, list
) {
55 if (sdata
->vif
.type
!= NL80211_IFTYPE_AP_VLAN
&&
56 sdata
->vif
.type
!= NL80211_IFTYPE_MONITOR
&&
57 netif_running(sdata
->dev
)) {
58 conf
.vif
= &sdata
->vif
;
59 conf
.type
= sdata
->vif
.type
;
60 conf
.mac_addr
= sdata
->dev
->dev_addr
;
61 drv_remove_interface(local
, &conf
);
65 /* flush again, in case driver queued work */
66 flush_workqueue(local
->hw
.workqueue
);
69 if (local
->open_count
) {
70 ieee80211_led_radio(local
, false);
77 * __ieee80211_resume() is a static inline which just calls
78 * ieee80211_reconfig(), which is also needed for hardware
79 * hang/firmware failure/etc. recovery.