aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/chan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/chan.c')
-rw-r--r--net/wireless/chan.c56
1 files changed, 17 insertions, 39 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index bf1737fc9a7e..d92d088026bf 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -10,38 +10,6 @@
10#include "core.h" 10#include "core.h"
11 11
12struct ieee80211_channel * 12struct ieee80211_channel *
13rdev_fixed_channel(struct cfg80211_registered_device *rdev,
14 struct wireless_dev *for_wdev)
15{
16 struct wireless_dev *wdev;
17 struct ieee80211_channel *result = NULL;
18
19 WARN_ON(!mutex_is_locked(&rdev->devlist_mtx));
20
21 list_for_each_entry(wdev, &rdev->netdev_list, list) {
22 if (wdev == for_wdev)
23 continue;
24
25 /*
26 * Lock manually to tell lockdep about allowed
27 * nesting here if for_wdev->mtx is held already.
28 * This is ok as it's all under the rdev devlist
29 * mutex and as such can only be done once at any
30 * given time.
31 */
32 mutex_lock_nested(&wdev->mtx, SINGLE_DEPTH_NESTING);
33 if (wdev->current_bss)
34 result = wdev->current_bss->pub.channel;
35 wdev_unlock(wdev);
36
37 if (result)
38 break;
39 }
40
41 return result;
42}
43
44struct ieee80211_channel *
45rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 13rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
46 int freq, enum nl80211_channel_type channel_type) 14 int freq, enum nl80211_channel_type channel_type)
47{ 15{
@@ -75,15 +43,22 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
75 return chan; 43 return chan;
76} 44}
77 45
78int rdev_set_freq(struct cfg80211_registered_device *rdev, 46int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
79 struct wireless_dev *for_wdev, 47 struct wireless_dev *wdev, int freq,
80 int freq, enum nl80211_channel_type channel_type) 48 enum nl80211_channel_type channel_type)
81{ 49{
82 struct ieee80211_channel *chan; 50 struct ieee80211_channel *chan;
83 int result; 51 int result;
84 52
85 if (rdev_fixed_channel(rdev, for_wdev)) 53 if (wdev->iftype == NL80211_IFTYPE_MONITOR)
86 return -EBUSY; 54 wdev = NULL;
55
56 if (wdev) {
57 ASSERT_WDEV_LOCK(wdev);
58
59 if (!netif_running(wdev->netdev))
60 return -ENETDOWN;
61 }
87 62
88 if (!rdev->ops->set_channel) 63 if (!rdev->ops->set_channel)
89 return -EOPNOTSUPP; 64 return -EOPNOTSUPP;
@@ -92,11 +67,14 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
92 if (!chan) 67 if (!chan)
93 return -EINVAL; 68 return -EINVAL;
94 69
95 result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type); 70 result = rdev->ops->set_channel(&rdev->wiphy,
71 wdev ? wdev->netdev : NULL,
72 chan, channel_type);
96 if (result) 73 if (result)
97 return result; 74 return result;
98 75
99 rdev->channel = chan; 76 if (wdev)
77 wdev->channel = chan;
100 78
101 return 0; 79 return 0;
102} 80}