diff options
Diffstat (limited to 'net/ieee80211/softmac/ieee80211softmac_wx.c')
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 508 |
1 files changed, 0 insertions, 508 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c deleted file mode 100644 index e01b59aedc54..000000000000 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ /dev/null | |||
@@ -1,508 +0,0 @@ | |||
1 | /* | ||
2 | * This file contains our _wx handlers. Make sure you EXPORT_SYMBOL_GPL them | ||
3 | * | ||
4 | * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * Joseph Jezak <josejx@gentoo.org> | ||
6 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
7 | * Danny van Dyk <kugelfang@gentoo.org> | ||
8 | * Michael Buesch <mbuesch@freenet.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | * | ||
23 | * The full GNU General Public License is included in this distribution in the | ||
24 | * file called COPYING. | ||
25 | */ | ||
26 | |||
27 | #include "ieee80211softmac_priv.h" | ||
28 | |||
29 | #include <net/iw_handler.h> | ||
30 | /* for is_broadcast_ether_addr and is_zero_ether_addr */ | ||
31 | #include <linux/etherdevice.h> | ||
32 | |||
33 | int | ||
34 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, | ||
35 | struct iw_request_info *info, | ||
36 | union iwreq_data *data, | ||
37 | char *extra) | ||
38 | { | ||
39 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | ||
40 | return ieee80211softmac_start_scan(sm); | ||
41 | } | ||
42 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan); | ||
43 | |||
44 | |||
45 | /* if we're still scanning, return -EAGAIN so that userspace tools | ||
46 | * can get the complete scan results, otherwise return 0. */ | ||
47 | int | ||
48 | ieee80211softmac_wx_get_scan_results(struct net_device *net_dev, | ||
49 | struct iw_request_info *info, | ||
50 | union iwreq_data *data, | ||
51 | char *extra) | ||
52 | { | ||
53 | unsigned long flags; | ||
54 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | ||
55 | |||
56 | spin_lock_irqsave(&sm->lock, flags); | ||
57 | if (sm->scanning) { | ||
58 | spin_unlock_irqrestore(&sm->lock, flags); | ||
59 | return -EAGAIN; | ||
60 | } | ||
61 | spin_unlock_irqrestore(&sm->lock, flags); | ||
62 | return ieee80211_wx_get_scan(sm->ieee, info, data, extra); | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results); | ||
65 | |||
66 | int | ||
67 | ieee80211softmac_wx_set_essid(struct net_device *net_dev, | ||
68 | struct iw_request_info *info, | ||
69 | union iwreq_data *data, | ||
70 | char *extra) | ||
71 | { | ||
72 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | ||
73 | struct ieee80211softmac_auth_queue_item *authptr; | ||
74 | int length = 0; | ||
75 | DECLARE_MAC_BUF(mac); | ||
76 | |||
77 | check_assoc_again: | ||
78 | mutex_lock(&sm->associnfo.mutex); | ||
79 | if((sm->associnfo.associating || sm->associnfo.associated) && | ||
80 | (data->essid.flags && data->essid.length)) { | ||
81 | dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); | ||
82 | /* Cancel assoc work */ | ||
83 | cancel_delayed_work(&sm->associnfo.work); | ||
84 | /* We don't have to do this, but it's a little cleaner */ | ||
85 | list_for_each_entry(authptr, &sm->auth_queue, list) | ||
86 | cancel_delayed_work(&authptr->work); | ||
87 | sm->associnfo.bssvalid = 0; | ||
88 | sm->associnfo.bssfixed = 0; | ||
89 | sm->associnfo.associating = 0; | ||
90 | sm->associnfo.associated = 0; | ||
91 | /* We must unlock to avoid deadlocks with the assoc workqueue | ||
92 | * on the associnfo.mutex */ | ||
93 | mutex_unlock(&sm->associnfo.mutex); | ||
94 | flush_workqueue(sm->wq); | ||
95 | /* Avoid race! Check assoc status again. Maybe someone started an | ||
96 | * association while we flushed. */ | ||
97 | goto check_assoc_again; | ||
98 | } | ||
99 | |||
100 | sm->associnfo.static_essid = 0; | ||
101 | sm->associnfo.assoc_wait = 0; | ||
102 | |||
103 | if (data->essid.flags && data->essid.length) { | ||
104 | length = min((int)data->essid.length, IW_ESSID_MAX_SIZE); | ||
105 | if (length) { | ||
106 | memcpy(sm->associnfo.req_essid.data, extra, length); | ||
107 | sm->associnfo.static_essid = 1; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /* set our requested ESSID length. | ||
112 | * If applicable, we have already copied the data in */ | ||
113 | sm->associnfo.req_essid.len = length; | ||
114 | |||
115 | sm->associnfo.associating = 1; | ||
116 | /* queue lower level code to do work (if necessary) */ | ||
117 | queue_delayed_work(sm->wq, &sm->associnfo.work, 0); | ||
118 | |||
119 | mutex_unlock(&sm->associnfo.mutex); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); | ||
124 | |||
125 | int | ||
126 | ieee80211softmac_wx_get_essid(struct net_device *net_dev, | ||
127 | struct iw_request_info *info, | ||
128 | union iwreq_data *data, | ||
129 | char *extra) | ||
130 | { | ||
131 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | ||
132 | |||
133 | mutex_lock(&sm->associnfo.mutex); | ||
134 | /* If all fails, return ANY (empty) */ | ||
135 | data->essid.length = 0; | ||
136 | data->essid.flags = 0; /* active */ | ||
137 | |||
138 | /* If we have a statically configured ESSID then return it */ | ||
139 | if (sm->associnfo.static_essid) { | ||
140 | data->essid.length = sm->associnfo.req_essid.len; | ||
141 | data->essid.flags = 1; /* active */ | ||
142 | memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len); | ||
143 | dprintk(KERN_INFO PFX "Getting essid from req_essid\n"); | ||
144 | } else if (sm->associnfo.associated || sm->associnfo.associating) { | ||
145 | /* If we're associating/associated, return that */ | ||
146 | data->essid.length = sm->associnfo.associate_essid.len; | ||
147 | data->essid.flags = 1; /* active */ | ||
148 | memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); | ||
149 | dprintk(KERN_INFO PFX "Getting essid from associate_essid\n"); | ||
150 | } | ||
151 | mutex_unlock(&sm->associnfo.mutex); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); | ||
156 | |||
157 | int | ||
158 | ieee80211softmac_wx_set_rate(struct net_device *net_dev, | ||
159 | struct iw_request_info *info, | ||
160 | union iwreq_data *data, | ||
161 | char *extra) | ||
162 | { | ||
163 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | ||
164 | struct ieee80211_device *ieee = mac->ieee; | ||
165 | unsigned long flags; | ||
166 | s32 in_rate = data->bitrate.value; | ||
167 | u8 rate; | ||
168 | int is_ofdm = 0; | ||
169 | int err = -EINVAL; | ||
170 | |||
171 | if (in_rate == -1) { | ||
172 | if (ieee->modulation & IEEE80211_OFDM_MODULATION) | ||
173 | in_rate = 24000000; | ||
174 | else | ||
175 | in_rate = 11000000; | ||
176 | } | ||
177 | |||
178 | switch (in_rate) { | ||
179 | case 1000000: | ||
180 | rate = IEEE80211_CCK_RATE_1MB; | ||
181 | break; | ||
182 | case 2000000: | ||
183 | rate = IEEE80211_CCK_RATE_2MB; | ||
184 | break; | ||
185 | case 5500000: | ||
186 | rate = IEEE80211_CCK_RATE_5MB; | ||
187 | break; | ||
188 | case 11000000: | ||
189 | rate = IEEE80211_CCK_RATE_11MB; | ||
190 | break; | ||
191 | case 6000000: | ||
192 | rate = IEEE80211_OFDM_RATE_6MB; | ||
193 | is_ofdm = 1; | ||
194 | break; | ||
195 | case 9000000: | ||
196 | rate = IEEE80211_OFDM_RATE_9MB; | ||
197 | is_ofdm = 1; | ||
198 | break; | ||
199 | case 12000000: | ||
200 | rate = IEEE80211_OFDM_RATE_12MB; | ||
201 | is_ofdm = 1; | ||
202 | break; | ||
203 | case 18000000: | ||
204 | rate = IEEE80211_OFDM_RATE_18MB; | ||
205 | is_ofdm = 1; | ||
206 | break; | ||
207 | case 24000000: | ||
208 | rate = IEEE80211_OFDM_RATE_24MB; | ||
209 | is_ofdm = 1; | ||
210 | break; | ||
211 | case 36000000: | ||
212 | rate = IEEE80211_OFDM_RATE_36MB; | ||
213 | is_ofdm = 1; | ||
214 | break; | ||
215 | case 48000000: | ||
216 | rate = IEEE80211_OFDM_RATE_48MB; | ||
217 | is_ofdm = 1; | ||
218 | break; | ||
219 | case 54000000: | ||
220 | rate = IEEE80211_OFDM_RATE_54MB; | ||
221 | is_ofdm = 1; | ||
222 | break; | ||
223 | default: | ||
224 | goto out; | ||
225 | } | ||
226 | |||
227 | spin_lock_irqsave(&mac->lock, flags); | ||
228 | |||
229 | /* Check if correct modulation for this PHY. */ | ||
230 | if (is_ofdm && !(ieee->modulation & IEEE80211_OFDM_MODULATION)) | ||
231 | goto out_unlock; | ||
232 | |||
233 | mac->txrates.user_rate = rate; | ||
234 | ieee80211softmac_recalc_txrates(mac); | ||
235 | err = 0; | ||
236 | |||
237 | out_unlock: | ||
238 | spin_unlock_irqrestore(&mac->lock, flags); | ||
239 | out: | ||
240 | return err; | ||
241 | } | ||
242 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_rate); | ||
243 | |||
244 | int | ||
245 | ieee80211softmac_wx_get_rate(struct net_device *net_dev, | ||
246 | struct iw_request_info *info, | ||
247 | union iwreq_data *data, | ||
248 | char *extra) | ||
249 | { | ||
250 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | ||
251 | unsigned long flags; | ||
252 | int err = -EINVAL; | ||
253 | |||
254 | spin_lock_irqsave(&mac->lock, flags); | ||
255 | |||
256 | if (unlikely(!mac->running)) { | ||
257 | err = -ENODEV; | ||
258 | goto out_unlock; | ||
259 | } | ||
260 | |||
261 | switch (mac->txrates.default_rate) { | ||
262 | case IEEE80211_CCK_RATE_1MB: | ||
263 | data->bitrate.value = 1000000; | ||
264 | break; | ||
265 | case IEEE80211_CCK_RATE_2MB: | ||
266 | data->bitrate.value = 2000000; | ||
267 | break; | ||
268 | case IEEE80211_CCK_RATE_5MB: | ||
269 | data->bitrate.value = 5500000; | ||
270 | break; | ||
271 | case IEEE80211_CCK_RATE_11MB: | ||
272 | data->bitrate.value = 11000000; | ||
273 | break; | ||
274 | case IEEE80211_OFDM_RATE_6MB: | ||
275 | data->bitrate.value = 6000000; | ||
276 | break; | ||
277 | case IEEE80211_OFDM_RATE_9MB: | ||
278 | data->bitrate.value = 9000000; | ||
279 | break; | ||
280 | case IEEE80211_OFDM_RATE_12MB: | ||
281 | data->bitrate.value = 12000000; | ||
282 | break; | ||
283 | case IEEE80211_OFDM_RATE_18MB: | ||
284 | data->bitrate.value = 18000000; | ||
285 | break; | ||
286 | case IEEE80211_OFDM_RATE_24MB: | ||
287 | data->bitrate.value = 24000000; | ||
288 | break; | ||
289 | case IEEE80211_OFDM_RATE_36MB: | ||
290 | data->bitrate.value = 36000000; | ||
291 | break; | ||
292 | case IEEE80211_OFDM_RATE_48MB: | ||
293 | data->bitrate.value = 48000000; | ||
294 | break; | ||
295 | case IEEE80211_OFDM_RATE_54MB: | ||
296 | data->bitrate.value = 54000000; | ||
297 | break; | ||
298 | default: | ||
299 | assert(0); | ||
300 | goto out_unlock; | ||
301 | } | ||
302 | err = 0; | ||
303 | out_unlock: | ||
304 | spin_unlock_irqrestore(&mac->lock, flags); | ||
305 | |||
306 | return err; | ||
307 | } | ||
308 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_rate); | ||
309 | |||
310 | int | ||
311 | ieee80211softmac_wx_get_wap(struct net_device *net_dev, | ||
312 | struct iw_request_info *info, | ||
313 | union iwreq_data *data, | ||
314 | char *extra) | ||
315 | { | ||
316 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | ||
317 | int err = 0; | ||
318 | |||
319 | mutex_lock(&mac->associnfo.mutex); | ||
320 | if (mac->associnfo.bssvalid) | ||
321 | memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); | ||
322 | else | ||
323 | memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); | ||
324 | data->ap_addr.sa_family = ARPHRD_ETHER; | ||
325 | mutex_unlock(&mac->associnfo.mutex); | ||
326 | |||
327 | return err; | ||
328 | } | ||
329 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); | ||
330 | |||
331 | int | ||
332 | ieee80211softmac_wx_set_wap(struct net_device *net_dev, | ||
333 | struct iw_request_info *info, | ||
334 | union iwreq_data *data, | ||
335 | char *extra) | ||
336 | { | ||
337 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | ||
338 | |||
339 | /* sanity check */ | ||
340 | if (data->ap_addr.sa_family != ARPHRD_ETHER) { | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | mutex_lock(&mac->associnfo.mutex); | ||
345 | if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { | ||
346 | /* the bssid we have is not to be fixed any longer, | ||
347 | * and we should reassociate to the best AP. */ | ||
348 | mac->associnfo.bssfixed = 0; | ||
349 | /* force reassociation */ | ||
350 | mac->associnfo.bssvalid = 0; | ||
351 | if (mac->associnfo.associated) | ||
352 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); | ||
353 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { | ||
354 | /* the bssid we have is no longer fixed */ | ||
355 | mac->associnfo.bssfixed = 0; | ||
356 | } else { | ||
357 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { | ||
358 | if (mac->associnfo.associating || mac->associnfo.associated) { | ||
359 | /* bssid unchanged and associated or associating - just return */ | ||
360 | goto out; | ||
361 | } | ||
362 | } else { | ||
363 | /* copy new value in data->ap_addr.sa_data to bssid */ | ||
364 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); | ||
365 | } | ||
366 | /* tell the other code that this bssid should be used no matter what */ | ||
367 | mac->associnfo.bssfixed = 1; | ||
368 | /* queue associate if new bssid or (old one again and not associated) */ | ||
369 | queue_delayed_work(mac->wq, &mac->associnfo.work, 0); | ||
370 | } | ||
371 | |||
372 | out: | ||
373 | mutex_unlock(&mac->associnfo.mutex); | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); | ||
378 | |||
379 | int | ||
380 | ieee80211softmac_wx_set_genie(struct net_device *dev, | ||
381 | struct iw_request_info *info, | ||
382 | union iwreq_data *wrqu, | ||
383 | char *extra) | ||
384 | { | ||
385 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | ||
386 | unsigned long flags; | ||
387 | int err = 0; | ||
388 | char *buf; | ||
389 | int i; | ||
390 | |||
391 | mutex_lock(&mac->associnfo.mutex); | ||
392 | spin_lock_irqsave(&mac->lock, flags); | ||
393 | /* bleh. shouldn't be locked for that kmalloc... */ | ||
394 | |||
395 | if (wrqu->data.length) { | ||
396 | if ((wrqu->data.length < 2) || (extra[1]+2 != wrqu->data.length)) { | ||
397 | /* this is an IE, so the length must be | ||
398 | * correct. Is it possible though that | ||
399 | * more than one IE is passed in? | ||
400 | */ | ||
401 | err = -EINVAL; | ||
402 | goto out; | ||
403 | } | ||
404 | if (mac->wpa.IEbuflen <= wrqu->data.length) { | ||
405 | buf = kmalloc(wrqu->data.length, GFP_ATOMIC); | ||
406 | if (!buf) { | ||
407 | err = -ENOMEM; | ||
408 | goto out; | ||
409 | } | ||
410 | kfree(mac->wpa.IE); | ||
411 | mac->wpa.IE = buf; | ||
412 | mac->wpa.IEbuflen = wrqu->data.length; | ||
413 | } | ||
414 | memcpy(mac->wpa.IE, extra, wrqu->data.length); | ||
415 | dprintk(KERN_INFO PFX "generic IE set to "); | ||
416 | for (i=0;i<wrqu->data.length;i++) | ||
417 | dprintk("%.2x", (u8)mac->wpa.IE[i]); | ||
418 | dprintk("\n"); | ||
419 | mac->wpa.IElen = wrqu->data.length; | ||
420 | } else { | ||
421 | kfree(mac->wpa.IE); | ||
422 | mac->wpa.IE = NULL; | ||
423 | mac->wpa.IElen = 0; | ||
424 | mac->wpa.IEbuflen = 0; | ||
425 | } | ||
426 | |||
427 | out: | ||
428 | spin_unlock_irqrestore(&mac->lock, flags); | ||
429 | mutex_unlock(&mac->associnfo.mutex); | ||
430 | |||
431 | return err; | ||
432 | } | ||
433 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); | ||
434 | |||
435 | int | ||
436 | ieee80211softmac_wx_get_genie(struct net_device *dev, | ||
437 | struct iw_request_info *info, | ||
438 | union iwreq_data *wrqu, | ||
439 | char *extra) | ||
440 | { | ||
441 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | ||
442 | unsigned long flags; | ||
443 | int err = 0; | ||
444 | int space = wrqu->data.length; | ||
445 | |||
446 | mutex_lock(&mac->associnfo.mutex); | ||
447 | spin_lock_irqsave(&mac->lock, flags); | ||
448 | |||
449 | wrqu->data.length = 0; | ||
450 | |||
451 | if (mac->wpa.IE && mac->wpa.IElen) { | ||
452 | wrqu->data.length = mac->wpa.IElen; | ||
453 | if (mac->wpa.IElen <= space) | ||
454 | memcpy(extra, mac->wpa.IE, mac->wpa.IElen); | ||
455 | else | ||
456 | err = -E2BIG; | ||
457 | } | ||
458 | spin_unlock_irqrestore(&mac->lock, flags); | ||
459 | mutex_unlock(&mac->associnfo.mutex); | ||
460 | |||
461 | return err; | ||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); | ||
464 | |||
465 | int | ||
466 | ieee80211softmac_wx_set_mlme(struct net_device *dev, | ||
467 | struct iw_request_info *info, | ||
468 | union iwreq_data *wrqu, | ||
469 | char *extra) | ||
470 | { | ||
471 | struct ieee80211softmac_device *mac = ieee80211_priv(dev); | ||
472 | struct iw_mlme *mlme = (struct iw_mlme *)extra; | ||
473 | u16 reason = mlme->reason_code; | ||
474 | struct ieee80211softmac_network *net; | ||
475 | int err = -EINVAL; | ||
476 | |||
477 | mutex_lock(&mac->associnfo.mutex); | ||
478 | |||
479 | if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { | ||
480 | printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); | ||
481 | goto out; | ||
482 | } | ||
483 | |||
484 | switch (mlme->cmd) { | ||
485 | case IW_MLME_DEAUTH: | ||
486 | net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); | ||
487 | if (!net) { | ||
488 | printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); | ||
489 | goto out; | ||
490 | } | ||
491 | err = ieee80211softmac_deauth_req(mac, net, reason); | ||
492 | goto out; | ||
493 | case IW_MLME_DISASSOC: | ||
494 | ieee80211softmac_send_disassoc_req(mac, reason); | ||
495 | mac->associnfo.associated = 0; | ||
496 | mac->associnfo.associating = 0; | ||
497 | err = 0; | ||
498 | goto out; | ||
499 | default: | ||
500 | err = -EOPNOTSUPP; | ||
501 | } | ||
502 | |||
503 | out: | ||
504 | mutex_unlock(&mac->associnfo.mutex); | ||
505 | |||
506 | return err; | ||
507 | } | ||
508 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); | ||