diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-06-06 02:18:22 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-06-06 15:18:17 -0400 |
commit | e8c9bd5b8d807cfe6c923265969a523b1ba1e6c2 (patch) | |
tree | e36cab1a3b2fb25bdc84115e3472a19672045dbe /net/wireless | |
parent | 7c9c46c16d2d1d232f3296924162de293477f017 (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.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 |
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 | } |
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 | ||