2 * This file contains our _wx handlers. Make sure you EXPORT_SYMBOL_GPL them
5 #include "ieee80211softmac_priv.h"
7 #include <net/iw_handler.h>
11 ieee80211softmac_wx_trigger_scan(struct net_device
*net_dev
,
12 struct iw_request_info
*info
,
13 union iwreq_data
*data
,
16 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
17 return ieee80211softmac_start_scan(sm
);
19 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan
);
23 ieee80211softmac_wx_get_scan_results(struct net_device
*net_dev
,
24 struct iw_request_info
*info
,
25 union iwreq_data
*data
,
28 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
29 return ieee80211_wx_get_scan(sm
->ieee
, info
, data
, extra
);
31 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results
);
34 ieee80211softmac_wx_set_essid(struct net_device
*net_dev
,
35 struct iw_request_info
*info
,
36 union iwreq_data
*data
,
39 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
43 spin_lock_irqsave(&sm
->lock
, flags
);
45 sm
->associnfo
.static_essid
= 0;
47 if (data
->essid
.flags
&& data
->essid
.length
&& extra
/*required?*/) {
48 length
= min(data
->essid
.length
- 1, IW_ESSID_MAX_SIZE
);
50 memcpy(sm
->associnfo
.req_essid
.data
, extra
, length
);
51 sm
->associnfo
.static_essid
= 1;
54 sm
->associnfo
.scan_retry
= IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT
;
56 /* set our requested ESSID length.
57 * If applicable, we have already copied the data in */
58 sm
->associnfo
.req_essid
.len
= length
;
60 /* queue lower level code to do work (if necessary) */
61 schedule_work(&sm
->associnfo
.work
);
63 spin_unlock_irqrestore(&sm
->lock
, flags
);
66 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid
);
69 ieee80211softmac_wx_get_essid(struct net_device
*net_dev
,
70 struct iw_request_info
*info
,
71 union iwreq_data
*data
,
74 struct ieee80211softmac_device
*sm
= ieee80211_priv(net_dev
);
77 /* avoid getting inconsistent information */
78 spin_lock_irqsave(&sm
->lock
, flags
);
79 /* If all fails, return ANY (empty) */
80 data
->essid
.length
= 0;
81 data
->essid
.flags
= 0; /* active */
83 /* If we have a statically configured ESSID then return it */
84 if (sm
->associnfo
.static_essid
) {
85 data
->essid
.length
= sm
->associnfo
.req_essid
.len
;
86 data
->essid
.flags
= 1; /* active */
87 memcpy(extra
, sm
->associnfo
.req_essid
.data
, sm
->associnfo
.req_essid
.len
);
90 /* If we're associating/associated, return that */
91 if (sm
->associated
|| sm
->associnfo
.associating
) {
92 data
->essid
.length
= sm
->associnfo
.associate_essid
.len
;
93 data
->essid
.flags
= 1; /* active */
94 memcpy(extra
, sm
->associnfo
.associate_essid
.data
, sm
->associnfo
.associate_essid
.len
);
96 spin_unlock_irqrestore(&sm
->lock
, flags
);
99 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid
);
102 ieee80211softmac_wx_set_rate(struct net_device
*net_dev
,
103 struct iw_request_info
*info
,
104 union iwreq_data
*data
,
107 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
108 struct ieee80211_device
*ieee
= mac
->ieee
;
110 s32 in_rate
= data
->bitrate
.value
;
116 /* automatic detect */
117 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
125 rate
= IEEE80211_CCK_RATE_1MB
;
128 rate
= IEEE80211_CCK_RATE_2MB
;
131 rate
= IEEE80211_CCK_RATE_5MB
;
134 rate
= IEEE80211_CCK_RATE_11MB
;
137 rate
= IEEE80211_OFDM_RATE_6MB
;
141 rate
= IEEE80211_OFDM_RATE_9MB
;
145 rate
= IEEE80211_OFDM_RATE_12MB
;
149 rate
= IEEE80211_OFDM_RATE_18MB
;
153 rate
= IEEE80211_OFDM_RATE_24MB
;
157 rate
= IEEE80211_OFDM_RATE_36MB
;
161 rate
= IEEE80211_OFDM_RATE_48MB
;
165 rate
= IEEE80211_OFDM_RATE_54MB
;
172 spin_lock_irqsave(&mac
->lock
, flags
);
174 /* Check if correct modulation for this PHY. */
175 if (is_ofdm
&& !(ieee
->modulation
& IEEE80211_OFDM_MODULATION
))
178 mac
->txrates
.default_rate
= rate
;
179 mac
->txrates
.default_fallback
= lower_rate(mac
, rate
);
183 spin_unlock_irqrestore(&mac
->lock
, flags
);
187 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_rate
);
190 ieee80211softmac_wx_get_rate(struct net_device
*net_dev
,
191 struct iw_request_info
*info
,
192 union iwreq_data
*data
,
195 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
199 spin_lock_irqsave(&mac
->lock
, flags
);
200 switch (mac
->txrates
.default_rate
) {
201 case IEEE80211_CCK_RATE_1MB
:
202 data
->bitrate
.value
= 1000000;
204 case IEEE80211_CCK_RATE_2MB
:
205 data
->bitrate
.value
= 2000000;
207 case IEEE80211_CCK_RATE_5MB
:
208 data
->bitrate
.value
= 5500000;
210 case IEEE80211_CCK_RATE_11MB
:
211 data
->bitrate
.value
= 11000000;
213 case IEEE80211_OFDM_RATE_6MB
:
214 data
->bitrate
.value
= 6000000;
216 case IEEE80211_OFDM_RATE_9MB
:
217 data
->bitrate
.value
= 9000000;
219 case IEEE80211_OFDM_RATE_12MB
:
220 data
->bitrate
.value
= 12000000;
222 case IEEE80211_OFDM_RATE_18MB
:
223 data
->bitrate
.value
= 18000000;
225 case IEEE80211_OFDM_RATE_24MB
:
226 data
->bitrate
.value
= 24000000;
228 case IEEE80211_OFDM_RATE_36MB
:
229 data
->bitrate
.value
= 36000000;
231 case IEEE80211_OFDM_RATE_48MB
:
232 data
->bitrate
.value
= 48000000;
234 case IEEE80211_OFDM_RATE_54MB
:
235 data
->bitrate
.value
= 54000000;
243 spin_unlock_irqrestore(&mac
->lock
, flags
);
247 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_rate
);
250 ieee80211softmac_wx_get_wap(struct net_device
*net_dev
,
251 struct iw_request_info
*info
,
252 union iwreq_data
*data
,
255 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
259 spin_lock_irqsave(&mac
->lock
, flags
);
260 if (mac
->associnfo
.bssvalid
)
261 memcpy(data
->ap_addr
.sa_data
, mac
->associnfo
.bssid
, ETH_ALEN
);
263 memset(data
->ap_addr
.sa_data
, 0xff, ETH_ALEN
);
264 data
->ap_addr
.sa_family
= ARPHRD_ETHER
;
265 spin_unlock_irqrestore(&mac
->lock
, flags
);
268 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap
);
271 ieee80211softmac_wx_set_wap(struct net_device
*net_dev
,
272 struct iw_request_info
*info
,
273 union iwreq_data
*data
,
276 struct ieee80211softmac_device
*mac
= ieee80211_priv(net_dev
);
277 static const unsigned char any
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
278 static const unsigned char off
[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
282 if (data
->ap_addr
.sa_family
!= ARPHRD_ETHER
) {
286 spin_lock_irqsave(&mac
->lock
, flags
);
287 if (!memcmp(any
, data
->ap_addr
.sa_data
, ETH_ALEN
) ||
288 !memcmp(off
, data
->ap_addr
.sa_data
, ETH_ALEN
)) {
289 schedule_work(&mac
->associnfo
.work
);
292 if (!memcmp(mac
->associnfo
.bssid
, data
->ap_addr
.sa_data
, ETH_ALEN
)) {
293 if (mac
->associnfo
.associating
|| mac
->associated
) {
294 /* bssid unchanged and associated or associating - just return */
298 /* copy new value in data->ap_addr.sa_data to bssid */
299 memcpy(mac
->associnfo
.bssid
, data
->ap_addr
.sa_data
, ETH_ALEN
);
301 /* queue associate if new bssid or (old one again and not associated) */
302 schedule_work(&mac
->associnfo
.work
);
306 spin_unlock_irqrestore(&mac
->lock
, flags
);
309 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap
);
312 ieee80211softmac_wx_set_genie(struct net_device
*dev
,
313 struct iw_request_info
*info
,
314 union iwreq_data
*wrqu
,
317 struct ieee80211softmac_device
*mac
= ieee80211_priv(dev
);
323 spin_lock_irqsave(&mac
->lock
, flags
);
324 /* bleh. shouldn't be locked for that kmalloc... */
326 if (wrqu
->data
.length
) {
327 if ((wrqu
->data
.length
< 2) || (extra
[1]+2 != wrqu
->data
.length
)) {
328 /* this is an IE, so the length must be
329 * correct. Is it possible though that
330 * more than one IE is passed in?
335 if (mac
->wpa
.IEbuflen
<= wrqu
->data
.length
) {
336 buf
= kmalloc(wrqu
->data
.length
, GFP_ATOMIC
);
343 mac
->wpa
.IEbuflen
= wrqu
->data
.length
;
345 memcpy(mac
->wpa
.IE
, extra
, wrqu
->data
.length
);
346 dprintk(KERN_INFO PFX
"generic IE set to ");
347 for (i
=0;i
<wrqu
->data
.length
;i
++)
348 dprintk("%.2x", mac
->wpa
.IE
[i
]);
350 mac
->wpa
.IElen
= wrqu
->data
.length
;
355 mac
->wpa
.IEbuflen
= 0;
359 spin_unlock_irqrestore(&mac
->lock
, flags
);
362 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie
);
365 ieee80211softmac_wx_get_genie(struct net_device
*dev
,
366 struct iw_request_info
*info
,
367 union iwreq_data
*wrqu
,
370 struct ieee80211softmac_device
*mac
= ieee80211_priv(dev
);
373 int space
= wrqu
->data
.length
;
375 spin_lock_irqsave(&mac
->lock
, flags
);
377 wrqu
->data
.length
= 0;
379 if (mac
->wpa
.IE
&& mac
->wpa
.IElen
) {
380 wrqu
->data
.length
= mac
->wpa
.IElen
;
381 if (mac
->wpa
.IElen
<= space
)
382 memcpy(extra
, mac
->wpa
.IE
, mac
->wpa
.IElen
);
386 spin_unlock_irqrestore(&mac
->lock
, flags
);
389 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie
);