diff options
Diffstat (limited to 'net/wireless/mesh.c')
-rw-r--r-- | net/wireless/mesh.c | 59 |
1 files changed, 24 insertions, 35 deletions
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index c384e77ff77a..f9d6ce5cfabb 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <net/cfg80211.h> | 3 | #include <net/cfg80211.h> |
4 | #include "nl80211.h" | 4 | #include "nl80211.h" |
5 | #include "core.h" | 5 | #include "core.h" |
6 | #include "rdev-ops.h" | ||
6 | 7 | ||
7 | /* Default values, timeouts in ms */ | 8 | /* Default values, timeouts in ms */ |
8 | #define MESH_TTL 31 | 9 | #define MESH_TTL 31 |
@@ -72,8 +73,6 @@ const struct mesh_config default_mesh_config = { | |||
72 | 73 | ||
73 | const struct mesh_setup default_mesh_setup = { | 74 | const struct mesh_setup default_mesh_setup = { |
74 | /* cfg80211_join_mesh() will pick a channel if needed */ | 75 | /* cfg80211_join_mesh() will pick a channel if needed */ |
75 | .channel = NULL, | ||
76 | .channel_type = NL80211_CHAN_NO_HT, | ||
77 | .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, | 76 | .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, |
78 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, | 77 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, |
79 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, | 78 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, |
@@ -110,13 +109,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
110 | if (!rdev->ops->join_mesh) | 109 | if (!rdev->ops->join_mesh) |
111 | return -EOPNOTSUPP; | 110 | return -EOPNOTSUPP; |
112 | 111 | ||
113 | if (!setup->channel) { | 112 | if (!setup->chandef.chan) { |
114 | /* if no channel explicitly given, use preset channel */ | 113 | /* if no channel explicitly given, use preset channel */ |
115 | setup->channel = wdev->preset_chan; | 114 | setup->chandef = wdev->preset_chandef; |
116 | setup->channel_type = wdev->preset_chantype; | ||
117 | } | 115 | } |
118 | 116 | ||
119 | if (!setup->channel) { | 117 | if (!setup->chandef.chan) { |
120 | /* if we don't have that either, use the first usable channel */ | 118 | /* if we don't have that either, use the first usable channel */ |
121 | enum ieee80211_band band; | 119 | enum ieee80211_band band; |
122 | 120 | ||
@@ -136,35 +134,35 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
136 | IEEE80211_CHAN_DISABLED | | 134 | IEEE80211_CHAN_DISABLED | |
137 | IEEE80211_CHAN_RADAR)) | 135 | IEEE80211_CHAN_RADAR)) |
138 | continue; | 136 | continue; |
139 | setup->channel = chan; | 137 | setup->chandef.chan = chan; |
140 | break; | 138 | break; |
141 | } | 139 | } |
142 | 140 | ||
143 | if (setup->channel) | 141 | if (setup->chandef.chan) |
144 | break; | 142 | break; |
145 | } | 143 | } |
146 | 144 | ||
147 | /* no usable channel ... */ | 145 | /* no usable channel ... */ |
148 | if (!setup->channel) | 146 | if (!setup->chandef.chan) |
149 | return -EINVAL; | 147 | return -EINVAL; |
150 | 148 | ||
151 | setup->channel_type = NL80211_CHAN_NO_HT; | 149 | setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT; |
150 | setup->chandef.center_freq1 = setup->chandef.chan->center_freq; | ||
152 | } | 151 | } |
153 | 152 | ||
154 | if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, setup->channel, | 153 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) |
155 | setup->channel_type)) | ||
156 | return -EINVAL; | 154 | return -EINVAL; |
157 | 155 | ||
158 | err = cfg80211_can_use_chan(rdev, wdev, setup->channel, | 156 | err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan, |
159 | CHAN_MODE_SHARED); | 157 | CHAN_MODE_SHARED); |
160 | if (err) | 158 | if (err) |
161 | return err; | 159 | return err; |
162 | 160 | ||
163 | err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); | 161 | err = rdev_join_mesh(rdev, dev, conf, setup); |
164 | if (!err) { | 162 | if (!err) { |
165 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); | 163 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); |
166 | wdev->mesh_id_len = setup->mesh_id_len; | 164 | wdev->mesh_id_len = setup->mesh_id_len; |
167 | wdev->channel = setup->channel; | 165 | wdev->channel = setup->chandef.chan; |
168 | } | 166 | } |
169 | 167 | ||
170 | return err; | 168 | return err; |
@@ -187,20 +185,12 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
187 | return err; | 185 | return err; |
188 | } | 186 | } |
189 | 187 | ||
190 | int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, | 188 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, |
191 | struct wireless_dev *wdev, int freq, | 189 | struct wireless_dev *wdev, |
192 | enum nl80211_channel_type channel_type) | 190 | struct cfg80211_chan_def *chandef) |
193 | { | 191 | { |
194 | struct ieee80211_channel *channel; | ||
195 | int err; | 192 | int err; |
196 | 193 | ||
197 | channel = rdev_freq_to_chan(rdev, freq, channel_type); | ||
198 | if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, | ||
199 | channel, | ||
200 | channel_type)) { | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | /* | 194 | /* |
205 | * Workaround for libertas (only!), it puts the interface | 195 | * Workaround for libertas (only!), it puts the interface |
206 | * into mesh mode but doesn't implement join_mesh. Instead, | 196 | * into mesh mode but doesn't implement join_mesh. Instead, |
@@ -209,22 +199,21 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, | |||
209 | * compatible with 802.11 mesh. | 199 | * compatible with 802.11 mesh. |
210 | */ | 200 | */ |
211 | if (rdev->ops->libertas_set_mesh_channel) { | 201 | if (rdev->ops->libertas_set_mesh_channel) { |
212 | if (channel_type != NL80211_CHAN_NO_HT) | 202 | if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT) |
213 | return -EINVAL; | 203 | return -EINVAL; |
214 | 204 | ||
215 | if (!netif_running(wdev->netdev)) | 205 | if (!netif_running(wdev->netdev)) |
216 | return -ENETDOWN; | 206 | return -ENETDOWN; |
217 | 207 | ||
218 | err = cfg80211_can_use_chan(rdev, wdev, channel, | 208 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, |
219 | CHAN_MODE_SHARED); | 209 | CHAN_MODE_SHARED); |
220 | if (err) | 210 | if (err) |
221 | return err; | 211 | return err; |
222 | 212 | ||
223 | err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, | 213 | err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, |
224 | wdev->netdev, | 214 | chandef->chan); |
225 | channel); | ||
226 | if (!err) | 215 | if (!err) |
227 | wdev->channel = channel; | 216 | wdev->channel = chandef->chan; |
228 | 217 | ||
229 | return err; | 218 | return err; |
230 | } | 219 | } |
@@ -232,8 +221,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, | |||
232 | if (wdev->mesh_id_len) | 221 | if (wdev->mesh_id_len) |
233 | return -EBUSY; | 222 | return -EBUSY; |
234 | 223 | ||
235 | wdev->preset_chan = channel; | 224 | wdev->preset_chandef = *chandef; |
236 | wdev->preset_chantype = channel_type; | ||
237 | return 0; | 225 | return 0; |
238 | } | 226 | } |
239 | 227 | ||
@@ -242,6 +230,7 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, | |||
242 | { | 230 | { |
243 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 231 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
244 | 232 | ||
233 | trace_cfg80211_notify_new_peer_candidate(dev, macaddr); | ||
245 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) | 234 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) |
246 | return; | 235 | return; |
247 | 236 | ||
@@ -267,7 +256,7 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | |||
267 | if (!wdev->mesh_id_len) | 256 | if (!wdev->mesh_id_len) |
268 | return -ENOTCONN; | 257 | return -ENOTCONN; |
269 | 258 | ||
270 | err = rdev->ops->leave_mesh(&rdev->wiphy, dev); | 259 | err = rdev_leave_mesh(rdev, dev); |
271 | if (!err) { | 260 | if (!err) { |
272 | wdev->mesh_id_len = 0; | 261 | wdev->mesh_id_len = 0; |
273 | wdev->channel = NULL; | 262 | wdev->channel = NULL; |