aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-12-13 11:42:30 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 07:01:35 -0500
commit8a61af65c6d03781015315dbc43d0942a5b31db9 (patch)
tree624695ba646281508490cb1737fb69d8174fa87a /net
parent529ba6e9313dbe60dab7e72c6fdf647a012e9f5b (diff)
mac80211: fix channel context iteration
During suspend/resume channel contexts might be iterated even if they haven't been re-added to the driver, keep track of this and skip them in iteration. Also use the new status for sanity checks. Also clarify the fact that during HW restart all contexts are iterated over (thanks Eliad.) Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/chan.c3
-rw-r--r--net/mac80211/driver-ops.h15
-rw-r--r--net/mac80211/ieee80211_i.h1
3 files changed, 15 insertions, 4 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 80e55527504b..1bfe0a8b19d2 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -381,7 +381,8 @@ void ieee80211_iter_chan_contexts_atomic(
381 381
382 rcu_read_lock(); 382 rcu_read_lock();
383 list_for_each_entry_rcu(ctx, &local->chanctx_list, list) 383 list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
384 iter(hw, &ctx->conf, iter_data); 384 if (ctx->driver_present)
385 iter(hw, &ctx->conf, iter_data);
385 rcu_read_unlock(); 386 rcu_read_unlock();
386} 387}
387EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); 388EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 698dc7e6f309..608ced41548d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -913,6 +913,8 @@ static inline int drv_add_chanctx(struct ieee80211_local *local,
913 if (local->ops->add_chanctx) 913 if (local->ops->add_chanctx)
914 ret = local->ops->add_chanctx(&local->hw, &ctx->conf); 914 ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
915 trace_drv_return_int(local, ret); 915 trace_drv_return_int(local, ret);
916 if (!ret)
917 ctx->driver_present = true;
916 918
917 return ret; 919 return ret;
918} 920}
@@ -924,6 +926,7 @@ static inline void drv_remove_chanctx(struct ieee80211_local *local,
924 if (local->ops->remove_chanctx) 926 if (local->ops->remove_chanctx)
925 local->ops->remove_chanctx(&local->hw, &ctx->conf); 927 local->ops->remove_chanctx(&local->hw, &ctx->conf);
926 trace_drv_return_void(local); 928 trace_drv_return_void(local);
929 ctx->driver_present = false;
927} 930}
928 931
929static inline void drv_change_chanctx(struct ieee80211_local *local, 932static inline void drv_change_chanctx(struct ieee80211_local *local,
@@ -931,8 +934,10 @@ static inline void drv_change_chanctx(struct ieee80211_local *local,
931 u32 changed) 934 u32 changed)
932{ 935{
933 trace_drv_change_chanctx(local, ctx, changed); 936 trace_drv_change_chanctx(local, ctx, changed);
934 if (local->ops->change_chanctx) 937 if (local->ops->change_chanctx) {
938 WARN_ON_ONCE(!ctx->driver_present);
935 local->ops->change_chanctx(&local->hw, &ctx->conf, changed); 939 local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
940 }
936 trace_drv_return_void(local); 941 trace_drv_return_void(local);
937} 942}
938 943
@@ -945,10 +950,12 @@ static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
945 check_sdata_in_driver(sdata); 950 check_sdata_in_driver(sdata);
946 951
947 trace_drv_assign_vif_chanctx(local, sdata, ctx); 952 trace_drv_assign_vif_chanctx(local, sdata, ctx);
948 if (local->ops->assign_vif_chanctx) 953 if (local->ops->assign_vif_chanctx) {
954 WARN_ON_ONCE(!ctx->driver_present);
949 ret = local->ops->assign_vif_chanctx(&local->hw, 955 ret = local->ops->assign_vif_chanctx(&local->hw,
950 &sdata->vif, 956 &sdata->vif,
951 &ctx->conf); 957 &ctx->conf);
958 }
952 trace_drv_return_int(local, ret); 959 trace_drv_return_int(local, ret);
953 960
954 return ret; 961 return ret;
@@ -961,10 +968,12 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
961 check_sdata_in_driver(sdata); 968 check_sdata_in_driver(sdata);
962 969
963 trace_drv_unassign_vif_chanctx(local, sdata, ctx); 970 trace_drv_unassign_vif_chanctx(local, sdata, ctx);
964 if (local->ops->unassign_vif_chanctx) 971 if (local->ops->unassign_vif_chanctx) {
972 WARN_ON_ONCE(!ctx->driver_present);
965 local->ops->unassign_vif_chanctx(&local->hw, 973 local->ops->unassign_vif_chanctx(&local->hw,
966 &sdata->vif, 974 &sdata->vif,
967 &ctx->conf); 975 &ctx->conf);
976 }
968 trace_drv_return_void(local); 977 trace_drv_return_void(local);
969} 978}
970 979
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 38e7883cff23..23161189b173 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -685,6 +685,7 @@ struct ieee80211_chanctx {
685 685
686 enum ieee80211_chanctx_mode mode; 686 enum ieee80211_chanctx_mode mode;
687 int refcount; 687 int refcount;
688 bool driver_present;
688 689
689 struct ieee80211_chanctx_conf conf; 690 struct ieee80211_chanctx_conf conf;
690}; 691};