aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mesh.c')
-rw-r--r--net/wireless/mesh.c59
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
73const struct mesh_setup default_mesh_setup = { 74const 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
190int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, 188int 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;