diff options
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 8 | ||||
| -rw-r--r-- | net/mac80211/util.c | 19 |
2 files changed, 17 insertions, 10 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 588005c84a6d..a910bf1f092f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -662,6 +662,14 @@ struct ieee80211_local { | |||
| 662 | bool suspended; | 662 | bool suspended; |
| 663 | 663 | ||
| 664 | /* | 664 | /* |
| 665 | * Resuming is true while suspended, but when we're reprogramming the | ||
| 666 | * hardware -- at that time it's allowed to use ieee80211_queue_work() | ||
| 667 | * again even though some other parts of the stack are still suspended | ||
| 668 | * and we still drop received frames to avoid waking the stack. | ||
| 669 | */ | ||
| 670 | bool resuming; | ||
| 671 | |||
| 672 | /* | ||
| 665 | * quiescing is true during the suspend process _only_ to | 673 | * quiescing is true during the suspend process _only_ to |
| 666 | * ease timer cancelling etc. | 674 | * ease timer cancelling etc. |
| 667 | */ | 675 | */ |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aeb65b3d2295..e6c08da8da26 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | |||
| 520 | */ | 520 | */ |
| 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) |
| 522 | { | 522 | { |
| 523 | if (WARN(local->suspended, "queueing ieee80211 work while " | 523 | if (WARN(local->suspended && !local->resuming, |
| 524 | "going to suspend\n")) | 524 | "queueing ieee80211 work while going to suspend\n")) |
| 525 | return false; | 525 | return false; |
| 526 | 526 | ||
| 527 | return true; | 527 | return true; |
| 528 | } | 528 | } |
| @@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1025 | struct sta_info *sta; | 1025 | struct sta_info *sta; |
| 1026 | unsigned long flags; | 1026 | unsigned long flags; |
| 1027 | int res; | 1027 | int res; |
| 1028 | bool from_suspend = local->suspended; | ||
| 1029 | 1028 | ||
| 1030 | /* | 1029 | if (local->suspended) |
| 1031 | * We're going to start the hardware, at that point | 1030 | local->resuming = true; |
| 1032 | * we are no longer suspended and can RX frames. | ||
| 1033 | */ | ||
| 1034 | local->suspended = false; | ||
| 1035 | 1031 | ||
| 1036 | /* restart hardware */ | 1032 | /* restart hardware */ |
| 1037 | if (local->open_count) { | 1033 | if (local->open_count) { |
| @@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1129 | * If this is for hw restart things are still running. | 1125 | * If this is for hw restart things are still running. |
| 1130 | * We may want to change that later, however. | 1126 | * We may want to change that later, however. |
| 1131 | */ | 1127 | */ |
| 1132 | if (!from_suspend) | 1128 | if (!local->suspended) |
| 1133 | return 0; | 1129 | return 0; |
| 1134 | 1130 | ||
| 1135 | #ifdef CONFIG_PM | 1131 | #ifdef CONFIG_PM |
| 1132 | /* first set suspended false, then resuming */ | ||
| 1136 | local->suspended = false; | 1133 | local->suspended = false; |
| 1134 | mb(); | ||
| 1135 | local->resuming = false; | ||
| 1137 | 1136 | ||
| 1138 | list_for_each_entry(sdata, &local->interfaces, list) { | 1137 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 1139 | switch(sdata->vif.type) { | 1138 | switch(sdata->vif.type) { |
