aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-06-06 04:25:02 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-06-18 13:18:53 -0400
commit04800ada2acc3a9ffc754c1d73576cef326f3311 (patch)
treec3b298de7409ec82b19d206c66d84558c09637d6
parent58886a9011f8eae705b9f585ec6c80b34f3c4e6c (diff)
mac80211: stop Rx during HW reconfig
While HW reconfig is in progress, drop all incoming Rx. This prevents incoming packets from changing the internal state of the driver or calling callbacks of the low level driver while it is in inconsistent state. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/mac80211/rx.c4
-rw-r--r--net/mac80211/util.c3
4 files changed, 17 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6cbf5b68c89..ddf768f6350e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -881,6 +881,9 @@ struct ieee80211_local {
881 /* device is started */ 881 /* device is started */
882 bool started; 882 bool started;
883 883
884 /* device is during a HW reconfig */
885 bool in_reconfig;
886
884 /* wowlan is enabled -- don't reconfig on resume */ 887 /* wowlan is enabled -- don't reconfig on resume */
885 bool wowlan; 888 bool wowlan;
886 889
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d81c178c7712..976e41365c25 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -345,6 +345,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
345 ieee80211_stop_queues_by_reason(hw, 345 ieee80211_stop_queues_by_reason(hw,
346 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 346 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
347 347
348 /*
349 * Stop all Rx during the reconfig. We don't want state changes
350 * or driver callbacks while this is in progress.
351 */
352 local->in_reconfig = true;
353 barrier();
354
348 schedule_work(&local->restart_work); 355 schedule_work(&local->restart_work);
349} 356}
350EXPORT_SYMBOL(ieee80211_restart_hw); 357EXPORT_SYMBOL(ieee80211_restart_hw);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6fd2cb0838c4..072e8f3afa2b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3027,6 +3027,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
3027 if (unlikely(local->quiescing || local->suspended)) 3027 if (unlikely(local->quiescing || local->suspended))
3028 goto drop; 3028 goto drop;
3029 3029
3030 /* We might be during a HW reconfig, prevent Rx for the same reason */
3031 if (unlikely(local->in_reconfig))
3032 goto drop;
3033
3030 /* 3034 /*
3031 * The same happens when we're not even started, 3035 * The same happens when we're not even started,
3032 * but that's worth a warning. 3036 * but that's worth a warning.
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1df4019f294b..242ecde381f6 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1411,6 +1411,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1411 if (ieee80211_sdata_running(sdata)) 1411 if (ieee80211_sdata_running(sdata))
1412 ieee80211_enable_keys(sdata); 1412 ieee80211_enable_keys(sdata);
1413 1413
1414 local->in_reconfig = false;
1415 barrier();
1416
1414 wake_up: 1417 wake_up:
1415 /* 1418 /*
1416 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation 1419 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation