diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2014-04-09 09:29:27 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-04-25 11:08:29 -0400 |
commit | e3afb920227d37fe72914350c41621c028539077 (patch) | |
tree | 8a33d0983dd8db843e98ad52d590075f9c0fbc4e /net/mac80211 | |
parent | 484298ad1afaf249a4708a5091487132dae80bf9 (diff) |
mac80211: track reserved vifs in chanctx
This can be useful. Provides a more straghtforward
way to iterate over interfaces taking part in
chanctx reservation and allows tracking chanctx
usage explicitly.
The structure is protected by local->chanctx_mtx.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/chan.c | 14 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 1 |
3 files changed, 13 insertions, 4 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 504526c97867..79eac96d9e5f 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -277,6 +277,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
277 | return ERR_PTR(-ENOMEM); | 277 | return ERR_PTR(-ENOMEM); |
278 | 278 | ||
279 | INIT_LIST_HEAD(&ctx->assigned_vifs); | 279 | INIT_LIST_HEAD(&ctx->assigned_vifs); |
280 | INIT_LIST_HEAD(&ctx->reserved_vifs); | ||
280 | ctx->conf.def = *chandef; | 281 | ctx->conf.def = *chandef; |
281 | ctx->conf.rx_chains_static = 1; | 282 | ctx->conf.rx_chains_static = 1; |
282 | ctx->conf.rx_chains_dynamic = 1; | 283 | ctx->conf.rx_chains_dynamic = 1; |
@@ -731,16 +732,19 @@ void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, | |||
731 | 732 | ||
732 | int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata) | 733 | int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata) |
733 | { | 734 | { |
735 | struct ieee80211_chanctx *ctx = sdata->reserved_chanctx; | ||
736 | |||
734 | lockdep_assert_held(&sdata->local->chanctx_mtx); | 737 | lockdep_assert_held(&sdata->local->chanctx_mtx); |
735 | 738 | ||
736 | if (WARN_ON(!sdata->reserved_chanctx)) | 739 | if (WARN_ON(!ctx)) |
737 | return -EINVAL; | 740 | return -EINVAL; |
738 | 741 | ||
739 | if (--sdata->reserved_chanctx->refcount == 0) | 742 | list_del(&sdata->reserved_chanctx_list); |
740 | ieee80211_free_chanctx(sdata->local, sdata->reserved_chanctx); | ||
741 | |||
742 | sdata->reserved_chanctx = NULL; | 743 | sdata->reserved_chanctx = NULL; |
743 | 744 | ||
745 | if (--ctx->refcount == 0) | ||
746 | ieee80211_free_chanctx(sdata->local, ctx); | ||
747 | |||
744 | return 0; | 748 | return 0; |
745 | } | 749 | } |
746 | 750 | ||
@@ -788,6 +792,7 @@ int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata, | |||
788 | } | 792 | } |
789 | } | 793 | } |
790 | 794 | ||
795 | list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs); | ||
791 | new_ctx->refcount++; | 796 | new_ctx->refcount++; |
792 | sdata->reserved_chanctx = new_ctx; | 797 | sdata->reserved_chanctx = new_ctx; |
793 | sdata->reserved_chandef = *chandef; | 798 | sdata->reserved_chandef = *chandef; |
@@ -837,6 +842,7 @@ int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata, | |||
837 | ctx->refcount--; | 842 | ctx->refcount--; |
838 | sdata->reserved_chanctx = NULL; | 843 | sdata->reserved_chanctx = NULL; |
839 | sdata->radar_required = sdata->reserved_radar_required; | 844 | sdata->radar_required = sdata->reserved_radar_required; |
845 | list_del(&sdata->reserved_chanctx_list); | ||
840 | 846 | ||
841 | if (old_ctx == ctx) { | 847 | if (old_ctx == ctx) { |
842 | /* This is our own context, just change it */ | 848 | /* This is our own context, just change it */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3b3b45a21501..3eaf6d7fad52 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -692,6 +692,7 @@ struct ieee80211_chanctx { | |||
692 | struct rcu_head rcu_head; | 692 | struct rcu_head rcu_head; |
693 | 693 | ||
694 | struct list_head assigned_vifs; | 694 | struct list_head assigned_vifs; |
695 | struct list_head reserved_vifs; | ||
695 | 696 | ||
696 | enum ieee80211_chanctx_mode mode; | 697 | enum ieee80211_chanctx_mode mode; |
697 | int refcount; | 698 | int refcount; |
@@ -759,6 +760,7 @@ struct ieee80211_sub_if_data { | |||
759 | struct cfg80211_chan_def csa_chandef; | 760 | struct cfg80211_chan_def csa_chandef; |
760 | 761 | ||
761 | struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */ | 762 | struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */ |
763 | struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */ | ||
762 | 764 | ||
763 | /* context reservation -- protected with chanctx_mtx */ | 765 | /* context reservation -- protected with chanctx_mtx */ |
764 | struct ieee80211_chanctx *reserved_chanctx; | 766 | struct ieee80211_chanctx *reserved_chanctx; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index a562d0f489e1..e91569d887e3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1292,6 +1292,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1292 | INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); | 1292 | INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); |
1293 | INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work); | 1293 | INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work); |
1294 | INIT_LIST_HEAD(&sdata->assigned_chanctx_list); | 1294 | INIT_LIST_HEAD(&sdata->assigned_chanctx_list); |
1295 | INIT_LIST_HEAD(&sdata->reserved_chanctx_list); | ||
1295 | 1296 | ||
1296 | switch (type) { | 1297 | switch (type) { |
1297 | case NL80211_IFTYPE_P2P_GO: | 1298 | case NL80211_IFTYPE_P2P_GO: |