aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/libertas/cfg.c39
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/mesh.c7
-rw-r--r--drivers/net/wireless/orinoco/cfg.c9
-rw-r--r--include/net/cfg80211.h24
-rw-r--r--net/mac80211/cfg.c9
-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
13 files changed, 100 insertions, 106 deletions
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 2fa879b015b6..f4a203049fb4 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -435,24 +435,40 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
435 * Set Channel 435 * Set Channel
436 */ 436 */
437 437
438static int lbs_cfg_set_channel(struct wiphy *wiphy, 438static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
439 struct net_device *netdev, 439 struct ieee80211_channel *channel,
440 struct ieee80211_channel *channel, 440 enum nl80211_channel_type channel_type)
441 enum nl80211_channel_type channel_type)
442{ 441{
443 struct lbs_private *priv = wiphy_priv(wiphy); 442 struct lbs_private *priv = wiphy_priv(wiphy);
444 int ret = -ENOTSUPP; 443 int ret = -ENOTSUPP;
445 444
446 lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d, type %d", 445 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
447 netdev_name(netdev), channel->center_freq, channel_type); 446 channel->center_freq, channel_type);
448 447
449 if (channel_type != NL80211_CHAN_NO_HT) 448 if (channel_type != NL80211_CHAN_NO_HT)
450 goto out; 449 goto out;
451 450
452 if (netdev == priv->mesh_dev) 451 ret = lbs_set_channel(priv, channel->hw_value);
453 ret = lbs_mesh_set_channel(priv, channel->hw_value); 452
454 else 453 out:
455 ret = lbs_set_channel(priv, channel->hw_value); 454 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
455 return ret;
456}
457
458static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy,
459 struct net_device *netdev,
460 struct ieee80211_channel *channel)
461{
462 struct lbs_private *priv = wiphy_priv(wiphy);
463 int ret = -ENOTSUPP;
464
465 lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d",
466 netdev_name(netdev), channel->center_freq);
467
468 if (netdev != priv->mesh_dev)
469 goto out;
470
471 ret = lbs_mesh_set_channel(priv, channel->hw_value);
456 472
457 out: 473 out:
458 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 474 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -2029,7 +2045,8 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
2029 */ 2045 */
2030 2046
2031static struct cfg80211_ops lbs_cfg80211_ops = { 2047static struct cfg80211_ops lbs_cfg80211_ops = {
2032 .set_channel = lbs_cfg_set_channel, 2048 .set_monitor_channel = lbs_cfg_set_monitor_channel,
2049 .libertas_set_mesh_channel = lbs_cfg_set_mesh_channel,
2033 .scan = lbs_cfg_scan, 2050 .scan = lbs_cfg_scan,
2034 .connect = lbs_cfg_connect, 2051 .connect = lbs_cfg_connect,
2035 .disconnect = lbs_cfg_disconnect, 2052 .disconnect = lbs_cfg_disconnect,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 672005430aca..60996ce89f77 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -58,6 +58,7 @@ struct lbs_private {
58 uint16_t mesh_tlv; 58 uint16_t mesh_tlv;
59 u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1]; 59 u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
60 u8 mesh_ssid_len; 60 u8 mesh_ssid_len;
61 u8 mesh_channel;
61#endif 62#endif
62 63
63 /* Debugfs */ 64 /* Debugfs */
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index e87c031b298f..97807751ebcf 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -131,16 +131,13 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
131 131
132int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel) 132int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel)
133{ 133{
134 priv->mesh_channel = channel;
134 return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel); 135 return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel);
135} 136}
136 137
137static uint16_t lbs_mesh_get_channel(struct lbs_private *priv) 138static uint16_t lbs_mesh_get_channel(struct lbs_private *priv)
138{ 139{
139 struct wireless_dev *mesh_wdev = priv->mesh_dev->ieee80211_ptr; 140 return priv->mesh_channel ?: 1;
140 if (mesh_wdev->channel)
141 return mesh_wdev->channel->hw_value;
142 else
143 return 1;
144} 141}
145 142
146/*************************************************************************** 143/***************************************************************************
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index f7b15b8934fa..e15675585fb1 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -160,10 +160,9 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
160 return err; 160 return err;
161} 161}
162 162
163static int orinoco_set_channel(struct wiphy *wiphy, 163static int orinoco_set_monitor_channel(struct wiphy *wiphy,
164 struct net_device *netdev, 164 struct ieee80211_channel *chan,
165 struct ieee80211_channel *chan, 165 enum nl80211_channel_type channel_type)
166 enum nl80211_channel_type channel_type)
167{ 166{
168 struct orinoco_private *priv = wiphy_priv(wiphy); 167 struct orinoco_private *priv = wiphy_priv(wiphy);
169 int err = 0; 168 int err = 0;
@@ -286,7 +285,7 @@ static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed)
286 285
287const struct cfg80211_ops orinoco_cfg_ops = { 286const struct cfg80211_ops orinoco_cfg_ops = {
288 .change_virtual_intf = orinoco_change_vif, 287 .change_virtual_intf = orinoco_change_vif,
289 .set_channel = orinoco_set_channel, 288 .set_monitor_channel = orinoco_set_monitor_channel,
290 .scan = orinoco_scan, 289 .scan = orinoco_scan,
291 .set_wiphy_params = orinoco_set_wiphy_params, 290 .set_wiphy_params = orinoco_set_wiphy_params,
292}; 291};
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4c90c44b8b75..7319f25250b6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1420,11 +1420,14 @@ struct cfg80211_gtk_rekey_data {
1420 * 1420 *
1421 * @set_txq_params: Set TX queue parameters 1421 * @set_txq_params: Set TX queue parameters
1422 * 1422 *
1423 * @set_channel: Set channel for a given wireless interface. Some devices 1423 * @libertas_set_mesh_channel: Only for backward compatibility for libertas,
1424 * may support multi-channel operation (by channel hopping) so cfg80211 1424 * as it doesn't implement join_mesh and needs to set the channel to
1425 * doesn't verify much. Note, however, that the passed netdev may be 1425 * join the mesh instead.
1426 * %NULL as well if the user requested changing the channel for the 1426 *
1427 * device itself, or for a monitor interface. 1427 * @set_monitor_channel: Set the monitor mode channel for the device. If other
1428 * interfaces are active this callback should reject the configuration.
1429 * If no interfaces are active or the device is down, the channel should
1430 * be stored for when a monitor interface becomes active.
1428 * @get_channel: Get the current operating channel, should return %NULL if 1431 * @get_channel: Get the current operating channel, should return %NULL if
1429 * there's no single defined operating channel if for example the 1432 * there's no single defined operating channel if for example the
1430 * device implements channel hopping for multi-channel virtual interfaces. 1433 * device implements channel hopping for multi-channel virtual interfaces.
@@ -1614,9 +1617,13 @@ struct cfg80211_ops {
1614 int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev, 1617 int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev,
1615 struct ieee80211_txq_params *params); 1618 struct ieee80211_txq_params *params);
1616 1619
1617 int (*set_channel)(struct wiphy *wiphy, struct net_device *dev, 1620 int (*libertas_set_mesh_channel)(struct wiphy *wiphy,
1618 struct ieee80211_channel *chan, 1621 struct net_device *dev,
1619 enum nl80211_channel_type channel_type); 1622 struct ieee80211_channel *chan);
1623
1624 int (*set_monitor_channel)(struct wiphy *wiphy,
1625 struct ieee80211_channel *chan,
1626 enum nl80211_channel_type channel_type);
1620 1627
1621 int (*scan)(struct wiphy *wiphy, struct net_device *dev, 1628 int (*scan)(struct wiphy *wiphy, struct net_device *dev,
1622 struct cfg80211_scan_request *request); 1629 struct cfg80211_scan_request *request);
@@ -2325,7 +2332,6 @@ struct wireless_dev {
2325 spinlock_t event_lock; 2332 spinlock_t event_lock;
2326 2333
2327 struct cfg80211_internal_bss *current_bss; /* associated / joined */ 2334 struct cfg80211_internal_bss *current_bss; /* associated / joined */
2328 struct ieee80211_channel *channel;
2329 struct ieee80211_channel *preset_chan; 2335 struct ieee80211_channel *preset_chan;
2330 enum nl80211_channel_type preset_chantype; 2336 enum nl80211_channel_type preset_chantype;
2331 2337
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 50aea1ac7e03..d99359a6f76d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -709,6 +709,13 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
709 return 0; 709 return 0;
710} 710}
711 711
712static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
713 struct ieee80211_channel *chan,
714 enum nl80211_channel_type channel_type)
715{
716 return ieee80211_set_channel(wiphy, NULL, chan, channel_type);
717}
718
712static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 719static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
713 const u8 *resp, size_t resp_len) 720 const u8 *resp, size_t resp_len)
714{ 721{
@@ -2932,7 +2939,7 @@ struct cfg80211_ops mac80211_config_ops = {
2932#endif 2939#endif
2933 .change_bss = ieee80211_change_bss, 2940 .change_bss = ieee80211_change_bss,
2934 .set_txq_params = ieee80211_set_txq_params, 2941 .set_txq_params = ieee80211_set_txq_params,
2935 .set_channel = ieee80211_set_channel, 2942 .set_monitor_channel = ieee80211_set_monitor_channel,
2936 .suspend = ieee80211_suspend, 2943 .suspend = ieee80211_suspend,
2937 .resume = ieee80211_resume, 2944 .resume = ieee80211_resume,
2938 .scan = ieee80211_scan, 2945 .scan = ieee80211_scan,
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