aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-26 08:55:08 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-16 14:22:46 -0400
commitfe57d9f5c0a2c1ef97ba8cdc42cfda5743f287b8 (patch)
treea155a8bb9165b092703bec542aeaf0b707afa392 /net
parente269d8600a8f6a9f2387b3f283bfb579a5479dc3 (diff)
mac80211: track whether to use channel contexts
Depending on the driver, channel contexts may be used or not. If they are used, the driver must have support for hardware scan and remain-on-channel; otherwise the driver must not advertise support for multiple channels. Also prohibit WDS type interfaces when channel contexts are to be used as there's no clear definition of which channel they use. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c22
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/scan.c4
5 files changed, 37 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 05f3a313db88..70a5d262815f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2189,6 +2189,9 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2189 2189
2190 lockdep_assert_held(&local->mtx); 2190 lockdep_assert_held(&local->mtx);
2191 2191
2192 if (local->use_chanctx && !local->ops->remain_on_channel)
2193 return -EOPNOTSUPP;
2194
2192 roc = kzalloc(sizeof(*roc), GFP_KERNEL); 2195 roc = kzalloc(sizeof(*roc), GFP_KERNEL);
2193 if (!roc) 2196 if (!roc)
2194 return -ENOMEM; 2197 return -ENOMEM;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9a058e58d53e..8fa00adcb8c0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -882,6 +882,8 @@ struct ieee80211_local {
882 882
883 bool wiphy_ciphers_allocated; 883 bool wiphy_ciphers_allocated;
884 884
885 bool use_chanctx;
886
885 /* protects the aggregated multicast list and filter calls */ 887 /* protects the aggregated multicast list and filter calls */
886 spinlock_t filter_lock; 888 spinlock_t filter_lock;
887 889
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d709a5d42f69..0dd1ea241c54 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -540,6 +540,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
540 struct ieee80211_local *local; 540 struct ieee80211_local *local;
541 int priv_size, i; 541 int priv_size, i;
542 struct wiphy *wiphy; 542 struct wiphy *wiphy;
543 bool use_chanctx;
543 544
544 if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || 545 if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config ||
545 !ops->add_interface || !ops->remove_interface || 546 !ops->add_interface || !ops->remove_interface ||
@@ -555,6 +556,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
555 !!ops->unassign_vif_chanctx; 556 !!ops->unassign_vif_chanctx;
556 if (WARN_ON(i != 0 && i != 5)) 557 if (WARN_ON(i != 0 && i != 5))
557 return NULL; 558 return NULL;
559 use_chanctx = i == 5;
558 560
559 /* Ensure 32-byte alignment of our private data and hw private data. 561 /* Ensure 32-byte alignment of our private data and hw private data.
560 * We use the wiphy priv data for both our ieee80211_local and for 562 * We use the wiphy priv data for both our ieee80211_local and for
@@ -606,6 +608,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
606 local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); 608 local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
607 609
608 local->ops = ops; 610 local->ops = ops;
611 local->use_chanctx = use_chanctx;
609 612
610 /* set up some defaults */ 613 /* set up some defaults */
611 local->hw.queues = 1; 614 local->hw.queues = 1;
@@ -729,6 +732,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
729 if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) 732 if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
730 return -EINVAL; 733 return -EINVAL;
731 734
735 if (!local->use_chanctx) {
736 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
737 const struct ieee80211_iface_combination *comb;
738
739 comb = &local->hw.wiphy->iface_combinations[i];
740
741 if (comb->num_different_channels > 1)
742 return -EINVAL;
743 }
744
745 /*
746 * WDS is currently prohibited when channel contexts are used
747 * because there's no clear definition of which channel WDS
748 * type interfaces use
749 */
750 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS))
751 return -EINVAL;
752 }
753
732 /* Only HW csum features are currently compatible with mac80211 */ 754 /* Only HW csum features are currently compatible with mac80211 */
733 feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 755 feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
734 NETIF_F_HW_CSUM; 756 NETIF_F_HW_CSUM;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 83608ac16780..9c52fc4a045e 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -107,6 +107,9 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
107{ 107{
108 struct ieee80211_sub_if_data *sdata; 108 struct ieee80211_sub_if_data *sdata;
109 109
110 if (WARN_ON(local->use_chanctx))
111 return;
112
110 /* 113 /*
111 * notify the AP about us leaving the channel and stop all 114 * notify the AP about us leaving the channel and stop all
112 * STA interfaces. 115 * STA interfaces.
@@ -145,6 +148,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
145{ 148{
146 struct ieee80211_sub_if_data *sdata; 149 struct ieee80211_sub_if_data *sdata;
147 150
151 if (WARN_ON(local->use_chanctx))
152 return;
153
148 mutex_lock(&local->iflist_mtx); 154 mutex_lock(&local->iflist_mtx);
149 list_for_each_entry(sdata, &local->interfaces, list) { 155 list_for_each_entry(sdata, &local->interfaces, list) {
150 if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) 156 if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c4cdbde24fd3..fdaa505dab45 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -336,6 +336,10 @@ EXPORT_SYMBOL(ieee80211_scan_completed);
336 336
337static int ieee80211_start_sw_scan(struct ieee80211_local *local) 337static int ieee80211_start_sw_scan(struct ieee80211_local *local)
338{ 338{
339 /* Software scan is not supported in multi-channel cases */
340 if (local->use_chanctx)
341 return -EOPNOTSUPP;
342
339 /* 343 /*
340 * Hardware/driver doesn't support hw_scan, so use software 344 * Hardware/driver doesn't support hw_scan, so use software
341 * scanning instead. First send a nullfunc frame with power save 345 * scanning instead. First send a nullfunc frame with power save