diff options
-rw-r--r-- | include/net/mac80211.h | 5 | ||||
-rw-r--r-- | net/mac80211/chan.c | 3 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 15 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 |
4 files changed, 20 insertions, 4 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ee50c5eba50c..0978b0faa880 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -3754,6 +3754,11 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
3754 | * The iterator will not find a context that's being added (during | 3754 | * The iterator will not find a context that's being added (during |
3755 | * the driver callback to add it) but will find it while it's being | 3755 | * the driver callback to add it) but will find it while it's being |
3756 | * removed. | 3756 | * removed. |
3757 | * | ||
3758 | * Note that during hardware restart, all contexts that existed | ||
3759 | * before the restart are considered already present so will be | ||
3760 | * found while iterating, whether they've been re-added already | ||
3761 | * or not. | ||
3757 | */ | 3762 | */ |
3758 | void ieee80211_iter_chan_contexts_atomic( | 3763 | void ieee80211_iter_chan_contexts_atomic( |
3759 | struct ieee80211_hw *hw, | 3764 | struct ieee80211_hw *hw, |
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 | } |
387 | EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); | 388 | EXPORT_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 | ||
929 | static inline void drv_change_chanctx(struct ieee80211_local *local, | 932 | static 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 | }; |