aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2012-06-29 06:47:08 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-06-29 07:39:19 -0400
commite4e32459c2daea59516da59999706b357e6eb480 (patch)
tree110014ac72ebcf7aed16caa0fa83da75e319fa86 /net
parentd4e50c5917e110451ced8f8de594cea858791f37 (diff)
cfg80211: respect iface combinations when starting operation
devlist_mtx locking is changed to accomodate changes. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/ibss.c10
-rw-r--r--net/wireless/mesh.c12
-rw-r--r--net/wireless/mlme.c16
-rw-r--r--net/wireless/nl80211.c8
-rw-r--r--net/wireless/util.c9
6 files changed, 52 insertions, 5 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index b26695ad3e97..ca2b95f24846 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -990,7 +990,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
990 return notifier_from_errno(-EOPNOTSUPP); 990 return notifier_from_errno(-EOPNOTSUPP);
991 if (rfkill_blocked(rdev->rfkill)) 991 if (rfkill_blocked(rdev->rfkill))
992 return notifier_from_errno(-ERFKILL); 992 return notifier_from_errno(-ERFKILL);
993 mutex_lock(&rdev->devlist_mtx);
993 ret = cfg80211_can_add_interface(rdev, wdev->iftype); 994 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
995 mutex_unlock(&rdev->devlist_mtx);
994 if (ret) 996 if (ret)
995 return notifier_from_errno(ret); 997 return notifier_from_errno(ret);
996 cfg80211_lock_rdev(rdev); 998 cfg80211_lock_rdev(rdev);
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index b90fd86b2d18..ca5672f6ee2f 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -118,6 +118,16 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
118 wdev->wext.ibss.channel = params->channel; 118 wdev->wext.ibss.channel = params->channel;
119#endif 119#endif
120 wdev->sme_state = CFG80211_SME_CONNECTING; 120 wdev->sme_state = CFG80211_SME_CONNECTING;
121
122 err = cfg80211_can_use_chan(rdev, wdev, params->channel,
123 params->channel_fixed
124 ? CHAN_MODE_SHARED
125 : CHAN_MODE_EXCLUSIVE);
126 if (err) {
127 wdev->connect_keys = NULL;
128 return err;
129 }
130
121 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); 131 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
122 if (err) { 132 if (err) {
123 wdev->connect_keys = NULL; 133 wdev->connect_keys = NULL;
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index bab381344723..c384e77ff77a 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -155,6 +155,11 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
155 setup->channel_type)) 155 setup->channel_type))
156 return -EINVAL; 156 return -EINVAL;
157 157
158 err = cfg80211_can_use_chan(rdev, wdev, setup->channel,
159 CHAN_MODE_SHARED);
160 if (err)
161 return err;
162
158 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); 163 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
159 if (!err) { 164 if (!err) {
160 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); 165 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
@@ -173,9 +178,11 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
173 struct wireless_dev *wdev = dev->ieee80211_ptr; 178 struct wireless_dev *wdev = dev->ieee80211_ptr;
174 int err; 179 int err;
175 180
181 mutex_lock(&rdev->devlist_mtx);
176 wdev_lock(wdev); 182 wdev_lock(wdev);
177 err = __cfg80211_join_mesh(rdev, dev, setup, conf); 183 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
178 wdev_unlock(wdev); 184 wdev_unlock(wdev);
185 mutex_unlock(&rdev->devlist_mtx);
179 186
180 return err; 187 return err;
181} 188}
@@ -208,6 +215,11 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
208 if (!netif_running(wdev->netdev)) 215 if (!netif_running(wdev->netdev))
209 return -ENETDOWN; 216 return -ENETDOWN;
210 217
218 err = cfg80211_can_use_chan(rdev, wdev, channel,
219 CHAN_MODE_SHARED);
220 if (err)
221 return err;
222
211 err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, 223 err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy,
212 wdev->netdev, 224 wdev->netdev,
213 channel); 225 channel);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index a7882eb8c46e..d4fece3bb18a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -302,8 +302,14 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
302 if (!req.bss) 302 if (!req.bss)
303 return -ENOENT; 303 return -ENOENT;
304 304
305 err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
306 CHAN_MODE_SHARED);
307 if (err)
308 goto out;
309
305 err = rdev->ops->auth(&rdev->wiphy, dev, &req); 310 err = rdev->ops->auth(&rdev->wiphy, dev, &req);
306 311
312out:
307 cfg80211_put_bss(req.bss); 313 cfg80211_put_bss(req.bss);
308 return err; 314 return err;
309} 315}
@@ -317,11 +323,13 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
317{ 323{
318 int err; 324 int err;
319 325
326 mutex_lock(&rdev->devlist_mtx);
320 wdev_lock(dev->ieee80211_ptr); 327 wdev_lock(dev->ieee80211_ptr);
321 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 328 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
322 ssid, ssid_len, ie, ie_len, 329 ssid, ssid_len, ie, ie_len,
323 key, key_len, key_idx); 330 key, key_len, key_idx);
324 wdev_unlock(dev->ieee80211_ptr); 331 wdev_unlock(dev->ieee80211_ptr);
332 mutex_unlock(&rdev->devlist_mtx);
325 333
326 return err; 334 return err;
327} 335}
@@ -397,8 +405,14 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
397 return -ENOENT; 405 return -ENOENT;
398 } 406 }
399 407
408 err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
409 CHAN_MODE_SHARED);
410 if (err)
411 goto out;
412
400 err = rdev->ops->assoc(&rdev->wiphy, dev, &req); 413 err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
401 414
415out:
402 if (err) { 416 if (err) {
403 if (was_connected) 417 if (was_connected)
404 wdev->sme_state = CFG80211_SME_CONNECTED; 418 wdev->sme_state = CFG80211_SME_CONNECTED;
@@ -421,11 +435,13 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
421 struct wireless_dev *wdev = dev->ieee80211_ptr; 435 struct wireless_dev *wdev = dev->ieee80211_ptr;
422 int err; 436 int err;
423 437
438 mutex_lock(&rdev->devlist_mtx);
424 wdev_lock(wdev); 439 wdev_lock(wdev);
425 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, 440 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
426 ssid, ssid_len, ie, ie_len, use_mfp, crypt, 441 ssid, ssid_len, ie, ie_len, use_mfp, crypt,
427 assoc_flags, ht_capa, ht_capa_mask); 442 assoc_flags, ht_capa, ht_capa_mask);
428 wdev_unlock(wdev); 443 wdev_unlock(wdev);
444 mutex_unlock(&rdev->devlist_mtx);
429 445
430 return err; 446 return err;
431} 447}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5d29ed1f7c62..77102e66f1ea 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2478,6 +2478,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2478 params.channel_type)) 2478 params.channel_type))
2479 return -EINVAL; 2479 return -EINVAL;
2480 2480
2481 mutex_lock(&rdev->devlist_mtx);
2482 err = cfg80211_can_use_chan(rdev, wdev, params.channel,
2483 CHAN_MODE_SHARED);
2484 mutex_unlock(&rdev->devlist_mtx);
2485
2486 if (err)
2487 return err;
2488
2481 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params); 2489 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
2482 if (!err) { 2490 if (!err) {
2483 wdev->preset_chan = params.channel; 2491 wdev->preset_chan = params.channel;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4713cea9a2fa..a9260ac85cf1 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -805,8 +805,10 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
805 return -EBUSY; 805 return -EBUSY;
806 806
807 if (ntype != otype && netif_running(dev)) { 807 if (ntype != otype && netif_running(dev)) {
808 mutex_lock(&rdev->devlist_mtx);
808 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, 809 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
809 ntype); 810 ntype);
811 mutex_unlock(&rdev->devlist_mtx);
810 if (err) 812 if (err)
811 return err; 813 return err;
812 814
@@ -956,6 +958,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
956 int i, j; 958 int i, j;
957 959
958 ASSERT_RTNL(); 960 ASSERT_RTNL();
961 lockdep_assert_held(&rdev->devlist_mtx);
959 962
960 /* Always allow software iftypes */ 963 /* Always allow software iftypes */
961 if (rdev->wiphy.software_iftypes & BIT(iftype)) 964 if (rdev->wiphy.software_iftypes & BIT(iftype))
@@ -979,7 +982,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
979 break; 982 break;
980 } 983 }
981 984
982 mutex_lock(&rdev->devlist_mtx);
983 list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { 985 list_for_each_entry(wdev_iter, &rdev->netdev_list, list) {
984 if (wdev_iter == wdev) 986 if (wdev_iter == wdev)
985 continue; 987 continue;
@@ -999,10 +1001,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
999 if (!used_channels[i] || used_channels[i] == ch) 1001 if (!used_channels[i] || used_channels[i] == ch)
1000 break; 1002 break;
1001 1003
1002 if (i == CFG80211_MAX_NUM_DIFFERENT_CHANNELS) { 1004 if (i == CFG80211_MAX_NUM_DIFFERENT_CHANNELS)
1003 mutex_unlock(&rdev->devlist_mtx);
1004 return -EBUSY; 1005 return -EBUSY;
1005 }
1006 1006
1007 if (used_channels[i] == NULL) { 1007 if (used_channels[i] == NULL) {
1008 used_channels[i] = ch; 1008 used_channels[i] = ch;
@@ -1018,7 +1018,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1018 total++; 1018 total++;
1019 used_iftypes |= BIT(wdev_iter->iftype); 1019 used_iftypes |= BIT(wdev_iter->iftype);
1020 } 1020 }
1021 mutex_unlock(&rdev->devlist_mtx);
1022 1021
1023 if (total == 1) 1022 if (total == 1)
1024 return 0; 1023 return 0;