diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-03-27 18:20:27 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-04-08 03:17:00 -0400 |
commit | 3c3e21e7443bdb948437a6e925fd111e932dc083 (patch) | |
tree | f8d2035b81e1aef8c0f26ade67c9756da5109b2d /net | |
parent | c8f994eec2a966a7a5fb6a3be517e3ede6a3cafa (diff) |
mac80211: destroy virtual monitor interface across suspend
It has to be removed from the driver, but completely
destroying it helps handle unplug of a device during
suspend since then the channel context handling etc.
doesn't have to happen later when it's removed.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 4 | ||||
-rw-r--r-- | net/mac80211/pm.c | 6 | ||||
-rw-r--r-- | net/mac80211/util.c | 5 |
4 files changed, 11 insertions, 6 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 693c1812b7bc..55fb382a8199 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1336,6 +1336,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | |||
1336 | const int offset); | 1336 | const int offset); |
1337 | int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); | 1337 | int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); |
1338 | void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); | 1338 | void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); |
1339 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local); | ||
1340 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local); | ||
1339 | 1341 | ||
1340 | bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); | 1342 | bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); |
1341 | void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); | 1343 | void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 75b322f9d945..d0d5f20f1ec4 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -346,7 +346,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) | |||
346 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; | 346 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; |
347 | } | 347 | } |
348 | 348 | ||
349 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | 349 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local) |
350 | { | 350 | { |
351 | struct ieee80211_sub_if_data *sdata; | 351 | struct ieee80211_sub_if_data *sdata; |
352 | int ret = 0; | 352 | int ret = 0; |
@@ -400,7 +400,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
400 | return ret; | 400 | return ret; |
401 | } | 401 | } |
402 | 402 | ||
403 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | 403 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local) |
404 | { | 404 | { |
405 | struct ieee80211_sub_if_data *sdata; | 405 | struct ieee80211_sub_if_data *sdata; |
406 | 406 | ||
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index b98d927dd0f3..d1c021b62fe5 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -21,6 +21,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
21 | 21 | ||
22 | ieee80211_roc_purge(local, NULL); | 22 | ieee80211_roc_purge(local, NULL); |
23 | 23 | ||
24 | ieee80211_del_virtual_monitor(local); | ||
25 | |||
24 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | 26 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { |
25 | mutex_lock(&local->sta_mtx); | 27 | mutex_lock(&local->sta_mtx); |
26 | list_for_each_entry(sta, &local->sta_list, list) { | 28 | list_for_each_entry(sta, &local->sta_list, list) { |
@@ -103,10 +105,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
103 | drv_remove_interface(local, sdata); | 105 | drv_remove_interface(local, sdata); |
104 | } | 106 | } |
105 | 107 | ||
106 | sdata = rtnl_dereference(local->monitor_sdata); | ||
107 | if (sdata) | ||
108 | drv_remove_interface(local, sdata); | ||
109 | |||
110 | /* | 108 | /* |
111 | * We disconnected on all interfaces before suspend, all channel | 109 | * We disconnected on all interfaces before suspend, all channel |
112 | * contexts should be released. | 110 | * contexts should be released. |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f9581c6378ae..43465b6e4778 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1461,6 +1461,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1461 | /* add interfaces */ | 1461 | /* add interfaces */ |
1462 | sdata = rtnl_dereference(local->monitor_sdata); | 1462 | sdata = rtnl_dereference(local->monitor_sdata); |
1463 | if (sdata) { | 1463 | if (sdata) { |
1464 | /* in HW restart it exists already */ | ||
1465 | WARN_ON(local->resuming); | ||
1464 | res = drv_add_interface(local, sdata); | 1466 | res = drv_add_interface(local, sdata); |
1465 | if (WARN_ON(res)) { | 1467 | if (WARN_ON(res)) { |
1466 | rcu_assign_pointer(local->monitor_sdata, NULL); | 1468 | rcu_assign_pointer(local->monitor_sdata, NULL); |
@@ -1650,6 +1652,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1650 | local->in_reconfig = false; | 1652 | local->in_reconfig = false; |
1651 | barrier(); | 1653 | barrier(); |
1652 | 1654 | ||
1655 | if (local->monitors == local->open_count && local->monitors > 0) | ||
1656 | ieee80211_add_virtual_monitor(local); | ||
1657 | |||
1653 | /* | 1658 | /* |
1654 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1659 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
1655 | * sessions can be established after a resume. | 1660 | * sessions can be established after a resume. |