aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-06-06 02:18:22 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-06-06 15:18:17 -0400
commite8c9bd5b8d807cfe6c923265969a523b1ba1e6c2 (patch)
treee36cab1a3b2fb25bdc84115e3472a19672045dbe /net/wireless
parent7c9c46c16d2d1d232f3296924162de293477f017 (diff)
cfg80211: clarify set_channel APIs
Now that we've removed all uses of the set_channel API except for the monitor channel and in libertas, clarify this. Split the libertas mesh use into a new libertas_set_mesh_channel() operation, just to keep backward compatibility, and rename the normal set_channel() to set_monitor_channel(). Also describe the desired set_monitor_channel() semantics more clearly. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c43
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/mesh.c26
-rw-r--r--net/wireless/mlme.c2
-rw-r--r--net/wireless/nl80211.c21
-rw-r--r--net/wireless/wext-compat.c10
-rw-r--r--net/wireless/wext-sme.c10
7 files changed, 42 insertions, 75 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 20b87d895722..c1999e45a07c 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -78,50 +78,17 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
78} 78}
79EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); 79EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan);
80 80
81int cfg80211_set_freq(struct cfg80211_registered_device *rdev, 81int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
82 struct wireless_dev *wdev, int freq, 82 int freq, enum nl80211_channel_type chantype)
83 enum nl80211_channel_type channel_type)
84{ 83{
85 struct ieee80211_channel *chan; 84 struct ieee80211_channel *chan;
86 int result;
87 85
88 if (wdev && wdev->iftype == NL80211_IFTYPE_MONITOR) 86 if (!rdev->ops->set_monitor_channel)
89 wdev = NULL;
90
91 if (wdev) {
92 ASSERT_WDEV_LOCK(wdev);
93
94 if (!netif_running(wdev->netdev))
95 return -ENETDOWN;
96 }
97
98 if (!rdev->ops->set_channel)
99 return -EOPNOTSUPP; 87 return -EOPNOTSUPP;
100 88
101 chan = rdev_freq_to_chan(rdev, freq, channel_type); 89 chan = rdev_freq_to_chan(rdev, freq, chantype);
102 if (!chan) 90 if (!chan)
103 return -EINVAL; 91 return -EINVAL;
104 92
105 /* Both channels should be able to initiate communication */ 93 return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype);
106 if (wdev && (wdev->iftype == NL80211_IFTYPE_ADHOC ||
107 wdev->iftype == NL80211_IFTYPE_AP ||
108 wdev->iftype == NL80211_IFTYPE_AP_VLAN ||
109 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
110 wdev->iftype == NL80211_IFTYPE_P2P_GO) &&
111 !cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan, channel_type)) {
112 printk(KERN_DEBUG
113 "cfg80211: Secondary channel not allowed to beacon\n");
114 return -EINVAL;
115 }
116
117 result = rdev->ops->set_channel(&rdev->wiphy,
118 wdev ? wdev->netdev : NULL,
119 chan, channel_type);
120 if (result)
121 return result;
122
123 if (wdev)
124 wdev->channel = chan;
125
126 return 0;
127} 94}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 1d3d24126946..9348a47562a4 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -444,9 +444,8 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
444struct ieee80211_channel * 444struct ieee80211_channel *
445rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 445rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
446 int freq, enum nl80211_channel_type channel_type); 446 int freq, enum nl80211_channel_type channel_type);
447int cfg80211_set_freq(struct cfg80211_registered_device *rdev, 447int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
448 struct wireless_dev *wdev, int freq, 448 int freq, enum nl80211_channel_type chantype);
449 enum nl80211_channel_type channel_type);
450 449
451int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, 450int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
452 const u8 *rates, unsigned int n_rates, 451 const u8 *rates, unsigned int n_rates,
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 2e3b700eba32..b44c736bf9cf 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -179,6 +179,13 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
179{ 179{
180 struct ieee80211_channel *channel; 180 struct ieee80211_channel *channel;
181 181
182 channel = rdev_freq_to_chan(rdev, freq, channel_type);
183 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
184 channel,
185 channel_type)) {
186 return -EINVAL;
187 }
188
182 /* 189 /*
183 * Workaround for libertas (only!), it puts the interface 190 * Workaround for libertas (only!), it puts the interface
184 * into mesh mode but doesn't implement join_mesh. Instead, 191 * into mesh mode but doesn't implement join_mesh. Instead,
@@ -186,27 +193,20 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
186 * you set the channel. Note that the libertas mesh isn't 193 * you set the channel. Note that the libertas mesh isn't
187 * compatible with 802.11 mesh. 194 * compatible with 802.11 mesh.
188 */ 195 */
189 if (!rdev->ops->join_mesh) { 196 if (rdev->ops->libertas_set_mesh_channel) {
190 int err; 197 if (channel_type != NL80211_CHAN_NO_HT)
198 return -EINVAL;
191 199
192 if (!netif_running(wdev->netdev)) 200 if (!netif_running(wdev->netdev))
193 return -ENETDOWN; 201 return -ENETDOWN;
194 wdev_lock(wdev); 202 return rdev->ops->libertas_set_mesh_channel(&rdev->wiphy,
195 err = cfg80211_set_freq(rdev, wdev, freq, channel_type); 203 wdev->netdev,
196 wdev_unlock(wdev); 204 channel);
197
198 return err;
199 } 205 }
200 206
201 if (wdev->mesh_id_len) 207 if (wdev->mesh_id_len)
202 return -EBUSY; 208 return -EBUSY;
203 209
204 channel = rdev_freq_to_chan(rdev, freq, channel_type);
205 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
206 channel,
207 channel_type)) {
208 return -EINVAL;
209 }
210 wdev->preset_chan = channel; 210 wdev->preset_chan = channel;
211 wdev->preset_chantype = channel_type; 211 wdev->preset_chantype = channel_type;
212 return 0; 212 return 0;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index eb90988bbd36..da4406f11929 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -947,8 +947,6 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
947 if (WARN_ON(!chan)) 947 if (WARN_ON(!chan))
948 goto out; 948 goto out;
949 949
950 wdev->channel = chan;
951
952 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL); 950 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
953out: 951out:
954 wdev_unlock(wdev); 952 wdev_unlock(wdev);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b22f1f876881..5e29bd38e7df 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -921,7 +921,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
921 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) 921 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
922 goto nla_put_failure; 922 goto nla_put_failure;
923 } 923 }
924 if (dev->ops->set_channel || dev->ops->start_ap || 924 if (dev->ops->set_monitor_channel || dev->ops->start_ap ||
925 dev->ops->join_mesh) { 925 dev->ops->join_mesh) {
926 i++; 926 i++;
927 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) 927 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
@@ -1178,8 +1178,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
1178 * the channel in the start-ap or join-mesh commands instead. 1178 * the channel in the start-ap or join-mesh commands instead.
1179 * 1179 *
1180 * Monitors are special as they are normally slaved to 1180 * Monitors are special as they are normally slaved to
1181 * whatever else is going on, so they behave as though 1181 * whatever else is going on, so they have their own special
1182 * you tried setting the wiphy channel itself. 1182 * operation to set the monitor channel if possible.
1183 */ 1183 */
1184 return !wdev || 1184 return !wdev ||
1185 wdev->iftype == NL80211_IFTYPE_AP || 1185 wdev->iftype == NL80211_IFTYPE_AP ||
@@ -1217,6 +1217,10 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1217 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 1217 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1218 u32 freq; 1218 u32 freq;
1219 int result; 1219 int result;
1220 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1221
1222 if (wdev)
1223 iftype = wdev->iftype;
1220 1224
1221 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) 1225 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1222 return -EINVAL; 1226 return -EINVAL;
@@ -1231,7 +1235,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1231 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 1235 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1232 1236
1233 mutex_lock(&rdev->devlist_mtx); 1237 mutex_lock(&rdev->devlist_mtx);
1234 if (wdev) switch (wdev->iftype) { 1238 switch (iftype) {
1235 case NL80211_IFTYPE_AP: 1239 case NL80211_IFTYPE_AP:
1236 case NL80211_IFTYPE_P2P_GO: 1240 case NL80211_IFTYPE_P2P_GO:
1237 if (wdev->beacon_interval) { 1241 if (wdev->beacon_interval) {
@@ -1252,12 +1256,11 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1252 case NL80211_IFTYPE_MESH_POINT: 1256 case NL80211_IFTYPE_MESH_POINT:
1253 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); 1257 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type);
1254 break; 1258 break;
1259 case NL80211_IFTYPE_MONITOR:
1260 result = cfg80211_set_monitor_channel(rdev, freq, channel_type);
1261 break;
1255 default: 1262 default:
1256 wdev_lock(wdev); 1263 result = -EINVAL;
1257 result = cfg80211_set_freq(rdev, wdev, freq, channel_type);
1258 wdev_unlock(wdev);
1259 } else {
1260 result = cfg80211_set_freq(rdev, NULL, freq, channel_type);
1261 } 1264 }
1262 mutex_unlock(&rdev->devlist_mtx); 1265 mutex_unlock(&rdev->devlist_mtx);
1263 1266
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index faeb03548aa4..bc879833b21f 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -802,9 +802,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
802 if (freq == 0) 802 if (freq == 0)
803 return -EINVAL; 803 return -EINVAL;
804 mutex_lock(&rdev->devlist_mtx); 804 mutex_lock(&rdev->devlist_mtx);
805 wdev_lock(wdev); 805 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT);
806 err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
807 wdev_unlock(wdev);
808 mutex_unlock(&rdev->devlist_mtx); 806 mutex_unlock(&rdev->devlist_mtx);
809 return err; 807 return err;
810 case NL80211_IFTYPE_MESH_POINT: 808 case NL80211_IFTYPE_MESH_POINT:
@@ -848,11 +846,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
848 freq->e = 6; 846 freq->e = 6;
849 return 0; 847 return 0;
850 default: 848 default:
851 if (!wdev->channel) 849 return -EINVAL;
852 return -EINVAL;
853 freq->m = wdev->channel->center_freq;
854 freq->e = 6;
855 return 0;
856 } 850 }
857} 851}
858 852
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 7decbd357d51..1f773f668d1a 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -111,9 +111,15 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
111 111
112 wdev->wext.connect.channel = chan; 112 wdev->wext.connect.channel = chan;
113 113
114 /* SSID is not set, we just want to switch channel */ 114 /*
115 * SSID is not set, we just want to switch monitor channel,
116 * this is really just backward compatibility, if the SSID
117 * is set then we use the channel to select the BSS to use
118 * to connect to instead. If we were connected on another
119 * channel we disconnected above and reconnect below.
120 */
115 if (chan && !wdev->wext.connect.ssid_len) { 121 if (chan && !wdev->wext.connect.ssid_len) {
116 err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT); 122 err = cfg80211_set_monitor_channel(rdev, freq, NL80211_CHAN_NO_HT);
117 goto out; 123 goto out;
118 } 124 }
119 125