2 * This file contains our _wx handlers. Make sure you EXPORT_SYMBOL_GPL them
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>
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.
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
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
23 * The full GNU General Public License is included in this distribution in the
24 * file called COPYING.
27 #include "ieee80211softmac_priv.h"
29 #include <net/iw_handler.h>
33 ieee80211softmac_wx_trigger_scan(struct net_device
*net_dev
,
34 struct iw_request_info
*info
,
35 union iwreq_data
*data
,
38 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
39 return ieee80211softmac_start_scan(sm
);
41 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan
);
45 ieee80211softmac_wx_get_scan_results(struct net_device
*net_dev
,
46 struct iw_request_info
*info
,
47 union iwreq_data
*data
,
50 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
51 return ieee80211_wx_get_scan(sm
->ieee
, info
, data
, extra
);
53 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results
);
56 ieee80211softmac_wx_set_essid(struct net_device
*net_dev
,
57 struct iw_request_info
*info
,
58 union iwreq_data
*data
,
61 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
65 spin_lock_irqsave(&sm
->lock
, flags
);
67 sm
->associnfo
.static_essid
= 0;
69 if (data
->essid
.flags
&& data
->essid
.length
&& extra
/*required?*/) {
70 length
= min(data
->essid
.length
- 1, IW_ESSID_MAX_SIZE
);
72 memcpy(sm
->associnfo
.req_essid
.data
, extra
, length
);
73 sm
->associnfo
.static_essid
= 1;
76 sm
->associnfo
.scan_retry
= IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT
;
78 /* set our requested ESSID length.
79 * If applicable, we have already copied the data in */
80 sm
->associnfo
.req_essid
.len
= length
;
82 /* queue lower level code to do work (if necessary) */
83 schedule_work(&sm
->associnfo
.work
);
85 spin_unlock_irqrestore(&sm
->lock
, flags
);
88 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid
);
91 ieee80211softmac_wx_get_essid(struct net_device
*net_dev
,
92 struct iw_request_info
*info
,
93 union iwreq_data
*data
,
96 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
99 /* avoid getting inconsistent information */
100 spin_lock_irqsave(&sm
->lock
, flags
);
101 /* If all fails, return ANY (empty) */
102 data
->essid
.length
= 0;
103 data
->essid
.flags
= 0; /* active */
105 /* If we have a statically configured ESSID then return it */
106 if (sm
->associnfo
.static_essid
) {
107 data
->essid
.length
= sm
->associnfo
.req_essid
.len
;
108 data
->essid
.flags
= 1; /* active */
109 memcpy(extra
, sm
->associnfo
.req_essid
.data
, sm
->associnfo
.req_essid
.len
);
112 /* If we're associating/associated, return that */
113 if (sm
->associated
|| sm
->associnfo
.associating
) {
114 data
->essid
.length
= sm
->associnfo
.associate_essid
.len
;
115 data
->essid
.flags
= 1; /* active */
116 memcpy(extra
, sm
->associnfo
.associate_essid
.data
, sm
->associnfo
.associate_essid
.len
);
118 spin_unlock_irqrestore(&sm
->lock
, flags
);
121 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid
);
124 ieee80211softmac_wx_set_rate(struct net_device
*net_dev
,
125 struct iw_request_info
*info
,
126 union iwreq_data
*data
,
129 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
130 struct ieee80211_device
*ieee
= mac
->ieee
;
132 s32 in_rate
= data
->bitrate
.value
;
138 /* automatic detect */
139 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
147 rate
= IEEE80211_CCK_RATE_1MB
;
150 rate
= IEEE80211_CCK_RATE_2MB
;
153 rate
= IEEE80211_CCK_RATE_5MB
;
156 rate
= IEEE80211_CCK_RATE_11MB
;
159 rate
= IEEE80211_OFDM_RATE_6MB
;
163 rate
= IEEE80211_OFDM_RATE_9MB
;
167 rate
= IEEE80211_OFDM_RATE_12MB
;
171 rate
= IEEE80211_OFDM_RATE_18MB
;
175 rate
= IEEE80211_OFDM_RATE_24MB
;
179 rate
= IEEE80211_OFDM_RATE_36MB
;
183 rate
= IEEE80211_OFDM_RATE_48MB
;
187 rate
= IEEE80211_OFDM_RATE_54MB
;
194 spin_lock_irqsave(&mac
->lock
, flags
);
196 /* Check if correct modulation for this PHY. */
197 if (is_ofdm
&& !(ieee
->modulation
& IEEE80211_OFDM_MODULATION
))
200 mac
->txrates
.default_rate
= rate
;
201 mac
->txrates
.default_fallback
= lower_rate(mac
, rate
);
205 spin_unlock_irqrestore(&mac
->lock
, flags
);
209 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_rate
);
212 ieee80211softmac_wx_get_rate(struct net_device
*net_dev
,
213 struct iw_request_info
*info
,
214 union iwreq_data
*data
,
217 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
221 spin_lock_irqsave(&mac
->lock
, flags
);
222 switch (mac
->txrates
.default_rate
) {
223 case IEEE80211_CCK_RATE_1MB
:
224 data
->bitrate
.value
= 1000000;
226 case IEEE80211_CCK_RATE_2MB
:
227 data
->bitrate
.value
= 2000000;
229 case IEEE80211_CCK_RATE_5MB
:
230 data
->bitrate
.value
= 5500000;
232 case IEEE80211_CCK_RATE_11MB
:
233 data
->bitrate
.value
= 11000000;
235 case IEEE80211_OFDM_RATE_6MB
:
236 data
->bitrate
.value
= 6000000;
238 case IEEE80211_OFDM_RATE_9MB
:
239 data
->bitrate
.value
= 9000000;
241 case IEEE80211_OFDM_RATE_12MB
:
242 data
->bitrate
.value
= 12000000;
244 case IEEE80211_OFDM_RATE_18MB
:
245 data
->bitrate
.value
= 18000000;
247 case IEEE80211_OFDM_RATE_24MB
:
248 data
->bitrate
.value
= 24000000;
250 case IEEE80211_OFDM_RATE_36MB
:
251 data
->bitrate
.value
= 36000000;
253 case IEEE80211_OFDM_RATE_48MB
:
254 data
->bitrate
.value
= 48000000;
256 case IEEE80211_OFDM_RATE_54MB
:
257 data
->bitrate
.value
= 54000000;
265 spin_unlock_irqrestore(&mac
->lock
, flags
);
269 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_rate
);
272 ieee80211softmac_wx_get_wap(struct net_device
*net_dev
,
273 struct iw_request_info
*info
,
274 union iwreq_data
*data
,
277 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
281 spin_lock_irqsave(&mac
->lock
, flags
);
282 if (mac
->associnfo
.bssvalid
)
283 memcpy(data
->ap_addr
.sa_data
, mac
->associnfo
.bssid
, ETH_ALEN
);
285 memset(data
->ap_addr
.sa_data
, 0xff, ETH_ALEN
);
286 data
->ap_addr
.sa_family
= ARPHRD_ETHER
;
287 spin_unlock_irqrestore(&mac
->lock
, flags
);
290 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap
);
293 ieee80211softmac_wx_set_wap(struct net_device
*net_dev
,
294 struct iw_request_info
*info
,
295 union iwreq_data
*data
,
298 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
299 static const unsigned char any
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
300 static const unsigned char off
[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
304 if (data
->ap_addr
.sa_family
!= ARPHRD_ETHER
) {
308 spin_lock_irqsave(&mac
->lock
, flags
);
309 if (!memcmp(any
, data
->ap_addr
.sa_data
, ETH_ALEN
) ||
310 !memcmp(off
, data
->ap_addr
.sa_data
, ETH_ALEN
)) {
311 schedule_work(&mac
->associnfo
.work
);
314 if (!memcmp(mac
->associnfo
.bssid
, data
->ap_addr
.sa_data
, ETH_ALEN
)) {
315 if (mac
->associnfo
.associating
|| mac
->associated
) {
316 /* bssid unchanged and associated or associating - just return */
320 /* copy new value in data->ap_addr.sa_data to bssid */
321 memcpy(mac
->associnfo
.bssid
, data
->ap_addr
.sa_data
, ETH_ALEN
);
323 /* queue associate if new bssid or (old one again and not associated) */
324 schedule_work(&mac
->associnfo
.work
);
328 spin_unlock_irqrestore(&mac
->lock
, flags
);
331 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap
);
334 ieee80211softmac_wx_set_genie(struct net_device
*dev
,
335 struct iw_request_info
*info
,
336 union iwreq_data
*wrqu
,
339 struct ieee80211softmac_device
*mac
= ieee80211_priv(dev
);
345 spin_lock_irqsave(&mac
->lock
, flags
);
346 /* bleh. shouldn't be locked for that kmalloc... */
348 if (wrqu
->data
.length
) {
349 if ((wrqu
->data
.length
< 2) || (extra
[1]+2 != wrqu
->data
.length
)) {
350 /* this is an IE, so the length must be
351 * correct. Is it possible though that
352 * more than one IE is passed in?
357 if (mac
->wpa
.IEbuflen
<= wrqu
->data
.length
) {
358 buf
= kmalloc(wrqu
->data
.length
, GFP_ATOMIC
);
365 mac
->wpa
.IEbuflen
= wrqu
->data
.length
;
367 memcpy(mac
->wpa
.IE
, extra
, wrqu
->data
.length
);
368 dprintk(KERN_INFO PFX
"generic IE set to ");
369 for (i
=0;i
<wrqu
->data
.length
;i
++)
370 dprintk("%.2x", mac
->wpa
.IE
[i
]);
372 mac
->wpa
.IElen
= wrqu
->data
.length
;
377 mac
->wpa
.IEbuflen
= 0;
381 spin_unlock_irqrestore(&mac
->lock
, flags
);
384 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie
);
387 ieee80211softmac_wx_get_genie(struct net_device
*dev
,
388 struct iw_request_info
*info
,
389 union iwreq_data
*wrqu
,
392 struct ieee80211softmac_device
*mac
= ieee80211_priv(dev
);
395 int space
= wrqu
->data
.length
;
397 spin_lock_irqsave(&mac
->lock
, flags
);
399 wrqu
->data
.length
= 0;
401 if (mac
->wpa
.IE
&& mac
->wpa
.IElen
) {
402 wrqu
->data
.length
= mac
->wpa
.IElen
;
403 if (mac
->wpa
.IElen
<= space
)
404 memcpy(extra
, mac
->wpa
.IE
, mac
->wpa
.IElen
);
408 spin_unlock_irqrestore(&mac
->lock
, flags
);
411 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie
);