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 queue_work(sm->workqueue, &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 queue_work(mac->workqueue, &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 queue_work(mac->workqueue,&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);