diff options
-rw-r--r-- | drivers/net/wireless/libertas/cfg.c | 39 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/mesh.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/cfg.c | 9 | ||||
-rw-r--r-- | include/net/cfg80211.h | 24 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 9 | ||||
-rw-r--r-- | net/wireless/chan.c | 43 | ||||
-rw-r--r-- | net/wireless/core.h | 5 | ||||
-rw-r--r-- | net/wireless/mesh.c | 26 | ||||
-rw-r--r-- | net/wireless/mlme.c | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 21 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 10 | ||||
-rw-r--r-- | net/wireless/wext-sme.c | 10 |
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 | ||
438 | static int lbs_cfg_set_channel(struct wiphy *wiphy, | 438 | static 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 | |||
458 | static 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 | ||
2031 | static struct cfg80211_ops lbs_cfg80211_ops = { | 2047 | static 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 | ||
132 | int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel) | 132 | int 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 | ||
137 | static uint16_t lbs_mesh_get_channel(struct lbs_private *priv) | 138 | static 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 | ||
163 | static int orinoco_set_channel(struct wiphy *wiphy, | 163 | static 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 | ||
287 | const struct cfg80211_ops orinoco_cfg_ops = { | 286 | const 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 | ||
712 | static 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 | |||
712 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | 719 | static 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 | } |
79 | EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); | 79 | EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); |
80 | 80 | ||
81 | int cfg80211_set_freq(struct cfg80211_registered_device *rdev, | 81 | int 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, | |||
444 | struct ieee80211_channel * | 444 | struct ieee80211_channel * |
445 | rdev_freq_to_chan(struct cfg80211_registered_device *rdev, | 445 | rdev_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); |
447 | int cfg80211_set_freq(struct cfg80211_registered_device *rdev, | 447 | int 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 | ||
451 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, | 450 | int 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); |
953 | out: | 951 | out: |
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 | ||