- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / staging / rtl8187se / ieee80211 / ieee80211_wx.c
1 /******************************************************************************
2
3   Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5   Portions of this file are based on the WEP enablement code provided by the
6   Host AP project hostap-drivers v0.1.3
7   Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8   <jkmaline@cc.hut.fi>
9   Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11   This program is free software; you can redistribute it and/or modify it
12   under the terms of version 2 of the GNU General Public License as
13   published by the Free Software Foundation.
14
15   This program is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18   more details.
19
20   You should have received a copy of the GNU General Public License along with
21   this program; if not, write to the Free Software Foundation, Inc., 59
22   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23
24   The full GNU General Public License is included in this distribution in the
25   file called LICENSE.
26
27   Contact Information:
28   James P. Ketrenos <ipw2100-admin@linux.intel.com>
29   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31 ******************************************************************************/
32 #include <linux/wireless.h>
33 #include <linux/kmod.h>
34 #include <linux/module.h>
35
36 #include "ieee80211.h"
37 static const char *ieee80211_modes[] = {
38         "?", "a", "b", "ab", "g", "ag", "bg", "abg"
39 };
40
41 #define MAX_CUSTOM_LEN 64
42 static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
43                                            char *start, char *stop,
44                                            struct ieee80211_network *network,
45                                            struct iw_request_info *info)
46 {
47         char custom[MAX_CUSTOM_LEN];
48         char *p;
49         struct iw_event iwe;
50         int i, j;
51         u8 max_rate, rate;
52
53         /* First entry *MUST* be the AP MAC address */
54         iwe.cmd = SIOCGIWAP;
55         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
56         memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
57         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
58
59         /* Remaining entries will be displayed in the order we provide them */
60
61         /* Add the ESSID */
62         iwe.cmd = SIOCGIWESSID;
63         iwe.u.data.flags = 1;
64         //YJ,modified,080903,for hidden ap
65         //if (network->flags & NETWORK_EMPTY_ESSID) {
66         if (network->ssid_len == 0) {
67         //YJ,modified,080903,end
68                 iwe.u.data.length = sizeof("<hidden>");
69                 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
70         } else {
71                 iwe.u.data.length = min(network->ssid_len, (u8)32);
72                 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
73         }
74         //printk("ESSID: %s\n",network->ssid);
75         /* Add the protocol name */
76         iwe.cmd = SIOCGIWNAME;
77         snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
78         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
79
80         /* Add mode */
81         iwe.cmd = SIOCGIWMODE;
82         if (network->capability &
83             (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
84                 if (network->capability & WLAN_CAPABILITY_BSS)
85                         iwe.u.mode = IW_MODE_MASTER;
86                 else
87                         iwe.u.mode = IW_MODE_ADHOC;
88
89                 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
90         }
91
92         /* Add frequency/channel */
93         iwe.cmd = SIOCGIWFREQ;
94 /*      iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
95         iwe.u.freq.e = 3; */
96         iwe.u.freq.m = network->channel;
97         iwe.u.freq.e = 0;
98         iwe.u.freq.i = 0;
99         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
100
101         /* Add encryption capability */
102         iwe.cmd = SIOCGIWENCODE;
103         if (network->capability & WLAN_CAPABILITY_PRIVACY)
104                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
105         else
106                 iwe.u.data.flags = IW_ENCODE_DISABLED;
107         iwe.u.data.length = 0;
108         start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
109
110         /* Add basic and extended rates */
111         max_rate = 0;
112         p = custom;
113         p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
114         for (i = 0, j = 0; i < network->rates_len; ) {
115                 if (j < network->rates_ex_len &&
116                     ((network->rates_ex[j] & 0x7F) <
117                      (network->rates[i] & 0x7F)))
118                         rate = network->rates_ex[j++] & 0x7F;
119                 else
120                         rate = network->rates[i++] & 0x7F;
121                 if (rate > max_rate)
122                         max_rate = rate;
123                 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
124                               "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
125         }
126         for (; j < network->rates_ex_len; j++) {
127                 rate = network->rates_ex[j] & 0x7F;
128                 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
129                               "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
130                 if (rate > max_rate)
131                         max_rate = rate;
132         }
133
134         iwe.cmd = SIOCGIWRATE;
135         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
136         iwe.u.bitrate.value = max_rate * 500000;
137         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
138
139         iwe.cmd = IWEVCUSTOM;
140         iwe.u.data.length = p - custom;
141         if (iwe.u.data.length)
142                 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
143
144         /* Add quality statistics */
145         /* TODO: Fix these values... */
146         if (network->stats.signal == 0 || network->stats.rssi == 0)
147         printk("========>signal:%d, rssi:%d\n", network->stats.signal, network->stats.rssi);
148         iwe.cmd = IWEVQUAL;
149 //      printk("SIGNAL: %d,RSSI: %d,NOISE: %d\n",network->stats.signal,network->stats.rssi,network->stats.noise);
150         iwe.u.qual.qual = network->stats.signalstrength;
151         iwe.u.qual.level = network->stats.signal;
152         iwe.u.qual.noise = network->stats.noise;
153         iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
154         if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
155                 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
156         if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
157                 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
158         if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
159                 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
160         iwe.u.qual.updated = 7;
161         start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
162
163         iwe.cmd = IWEVCUSTOM;
164         p = custom;
165
166         iwe.u.data.length = p - custom;
167         if (iwe.u.data.length)
168                 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
169
170                 memset(&iwe, 0, sizeof(iwe));
171         if (network->wpa_ie_len) {
172         //      printk("wpa_ie_len:%d\n", network->wpa_ie_len);
173                 char buf[MAX_WPA_IE_LEN];
174                 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
175                 iwe.cmd = IWEVGENIE;
176                 iwe.u.data.length = network->wpa_ie_len;
177                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
178         }
179
180         memset(&iwe, 0, sizeof(iwe));
181         if (network->rsn_ie_len) {
182         //      printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
183                 char buf[MAX_WPA_IE_LEN];
184                 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
185                 iwe.cmd = IWEVGENIE;
186                 iwe.u.data.length = network->rsn_ie_len;
187                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
188         }
189
190         /* Add EXTRA: Age to display seconds since last beacon/probe response
191          * for given network. */
192         iwe.cmd = IWEVCUSTOM;
193         p = custom;
194         p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
195                       " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
196         iwe.u.data.length = p - custom;
197         if (iwe.u.data.length)
198                 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
199
200         return start;
201 }
202
203 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
204                           struct iw_request_info *info,
205                           union iwreq_data *wrqu, char *extra)
206 {
207         struct ieee80211_network *network;
208         unsigned long flags;
209         int err = 0;
210         char *ev = extra;
211         char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
212         //char *stop = ev + IW_SCAN_MAX_DATA;
213         int i = 0;
214
215         IEEE80211_DEBUG_WX("Getting scan\n");
216         down(&ieee->wx_sem);
217         spin_lock_irqsave(&ieee->lock, flags);
218
219         if(!ieee->bHwRadioOff)
220         {
221                 list_for_each_entry(network, &ieee->network_list, list) {
222                         i++;
223
224                         if((stop-ev)<200)
225                         {
226                                 err = -E2BIG;
227                                 break;
228                         }
229                         if (ieee->scan_age == 0 ||
230                             time_after(network->last_scanned + ieee->scan_age, jiffies))
231                         {
232                                 ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
233                         }
234                         else
235                                 IEEE80211_DEBUG_SCAN(
236                                         "Not showing network '%s ("
237                                         MAC_FMT ")' due to age (%lums).\n",
238                                         escape_essid(network->ssid,
239                                                      network->ssid_len),
240                                         MAC_ARG(network->bssid),
241                                         (jiffies - network->last_scanned) / (HZ / 100));
242                 }
243         }
244         spin_unlock_irqrestore(&ieee->lock, flags);
245         up(&ieee->wx_sem);
246         wrqu->data.length = ev -  extra;
247         wrqu->data.flags = 0;
248         IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
249
250         return err;
251 }
252
253 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
254                             struct iw_request_info *info,
255                             union iwreq_data *wrqu, char *keybuf)
256 {
257         struct iw_point *erq = &(wrqu->encoding);
258         struct net_device *dev = ieee->dev;
259         struct ieee80211_security sec = {
260                 .flags = 0
261         };
262         int i, key, key_provided, len;
263         struct ieee80211_crypt_data **crypt;
264
265         IEEE80211_DEBUG_WX("SET_ENCODE\n");
266
267         key = erq->flags & IW_ENCODE_INDEX;
268         if (key) {
269                 if (key > WEP_KEYS)
270                         return -EINVAL;
271                 key--;
272                 key_provided = 1;
273         } else {
274                 key_provided = 0;
275                 key = ieee->tx_keyidx;
276         }
277
278         IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
279                            "provided" : "default");
280
281         crypt = &ieee->crypt[key];
282
283         if (erq->flags & IW_ENCODE_DISABLED) {
284                 if (key_provided && *crypt) {
285                         IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
286                                            key);
287                         ieee80211_crypt_delayed_deinit(ieee, crypt);
288                 } else
289                         IEEE80211_DEBUG_WX("Disabling encryption.\n");
290
291                 /* Check all the keys to see if any are still configured,
292                  * and if no key index was provided, de-init them all */
293                 for (i = 0; i < WEP_KEYS; i++) {
294                         if (ieee->crypt[i] != NULL) {
295                                 if (key_provided)
296                                         break;
297                                 ieee80211_crypt_delayed_deinit(
298                                         ieee, &ieee->crypt[i]);
299                         }
300                 }
301
302                 if (i == WEP_KEYS) {
303                         sec.enabled = 0;
304                         sec.level = SEC_LEVEL_0;
305                         sec.flags |= SEC_ENABLED | SEC_LEVEL;
306                 }
307
308                 goto done;
309         }
310
311
312
313         sec.enabled = 1;
314         sec.flags |= SEC_ENABLED;
315
316         if (*crypt != NULL && (*crypt)->ops != NULL &&
317             strcmp((*crypt)->ops->name, "WEP") != 0) {
318                 /* changing to use WEP; deinit previously used algorithm
319                  * on this key */
320                 ieee80211_crypt_delayed_deinit(ieee, crypt);
321         }
322
323         if (*crypt == NULL) {
324                 struct ieee80211_crypt_data *new_crypt;
325
326                 /* take WEP into use */
327                 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
328                                     GFP_KERNEL);
329                 if (new_crypt == NULL)
330                         return -ENOMEM;
331                 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
332                 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
333                 if (!new_crypt->ops)
334                         new_crypt->ops = ieee80211_get_crypto_ops("WEP");
335
336                 if (new_crypt->ops)
337                         new_crypt->priv = new_crypt->ops->init(key);
338
339                 if (!new_crypt->ops || !new_crypt->priv) {
340                         kfree(new_crypt);
341                         new_crypt = NULL;
342
343                         printk(KERN_WARNING "%s: could not initialize WEP: "
344                                "load module ieee80211_crypt_wep\n",
345                                dev->name);
346                         return -EOPNOTSUPP;
347                 }
348                 *crypt = new_crypt;
349         }
350
351         /* If a new key was provided, set it up */
352         if (erq->length > 0) {
353                 len = erq->length <= 5 ? 5 : 13;
354                 memcpy(sec.keys[key], keybuf, erq->length);
355                 if (len > erq->length)
356                         memset(sec.keys[key] + erq->length, 0,
357                                len - erq->length);
358                 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
359                                    key, escape_essid(sec.keys[key], len),
360                                    erq->length, len);
361                 sec.key_sizes[key] = len;
362                 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
363                                        (*crypt)->priv);
364                 sec.flags |= (1 << key);
365                 /* This ensures a key will be activated if no key is
366                  * explicitely set */
367                 if (key == sec.active_key)
368                         sec.flags |= SEC_ACTIVE_KEY;
369                 ieee->tx_keyidx = key;//by wb 080312
370         } else {
371                 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
372                                              NULL, (*crypt)->priv);
373                 if (len == 0) {
374                         /* Set a default key of all 0 */
375                         IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
376                                            key);
377                         memset(sec.keys[key], 0, 13);
378                         (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
379                                                (*crypt)->priv);
380                         sec.key_sizes[key] = 13;
381                         sec.flags |= (1 << key);
382                 }
383
384                 /* No key data - just set the default TX key index */
385                 if (key_provided) {
386                         IEEE80211_DEBUG_WX(
387                                 "Setting key %d to default Tx key.\n", key);
388                         ieee->tx_keyidx = key;
389                         sec.active_key = key;
390                         sec.flags |= SEC_ACTIVE_KEY;
391                 }
392         }
393
394  done:
395         ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
396         sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
397         sec.flags |= SEC_AUTH_MODE;
398         IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
399                            "OPEN" : "SHARED KEY");
400
401         /* For now we just support WEP, so only set that security level...
402          * TODO: When WPA is added this is one place that needs to change */
403         sec.flags |= SEC_LEVEL;
404         sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
405
406         if (ieee->set_security)
407                 ieee->set_security(dev, &sec);
408
409         /* Do not reset port if card is in Managed mode since resetting will
410          * generate new IEEE 802.11 authentication which may end up in looping
411          * with IEEE 802.1X.  If your hardware requires a reset after WEP
412          * configuration (for example... Prism2), implement the reset_port in
413          * the callbacks structures used to initialize the 802.11 stack. */
414         if (ieee->reset_on_keychange &&
415             ieee->iw_mode != IW_MODE_INFRA &&
416             ieee->reset_port && ieee->reset_port(dev)) {
417                 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
418                 return -EINVAL;
419         }
420         return 0;
421 }
422
423 int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
424                             struct iw_request_info *info,
425                             union iwreq_data *wrqu, char *keybuf)
426 {
427         struct iw_point *erq = &(wrqu->encoding);
428         int len, key;
429         struct ieee80211_crypt_data *crypt;
430
431         IEEE80211_DEBUG_WX("GET_ENCODE\n");
432
433         if(ieee->iw_mode == IW_MODE_MONITOR)
434                 return -1;
435
436         key = erq->flags & IW_ENCODE_INDEX;
437         if (key) {
438                 if (key > WEP_KEYS)
439                         return -EINVAL;
440                 key--;
441         } else
442                 key = ieee->tx_keyidx;
443
444         crypt = ieee->crypt[key];
445         erq->flags = key + 1;
446
447         if (crypt == NULL || crypt->ops == NULL) {
448                 erq->length = 0;
449                 erq->flags |= IW_ENCODE_DISABLED;
450                 return 0;
451         }
452
453         if (strcmp(crypt->ops->name, "WEP") != 0) {
454                 /* only WEP is supported with wireless extensions, so just
455                  * report that encryption is used */
456                 erq->length = 0;
457                 erq->flags |= IW_ENCODE_ENABLED;
458                 return 0;
459         }
460
461         len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
462         erq->length = (len >= 0 ? len : 0);
463
464         erq->flags |= IW_ENCODE_ENABLED;
465
466         if (ieee->open_wep)
467                 erq->flags |= IW_ENCODE_OPEN;
468         else
469                 erq->flags |= IW_ENCODE_RESTRICTED;
470
471         return 0;
472 }
473
474 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
475                                struct iw_request_info *info,
476                                union iwreq_data *wrqu, char *extra)
477 {
478         struct net_device *dev = ieee->dev;
479         struct iw_point *encoding = &wrqu->encoding;
480         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
481         int i, idx, ret = 0;
482         int group_key = 0;
483         const char *alg;
484         struct ieee80211_crypto_ops *ops;
485         struct ieee80211_crypt_data **crypt;
486
487         struct ieee80211_security sec = {
488                 .flags = 0,
489         };
490         //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
491         idx = encoding->flags & IW_ENCODE_INDEX;
492         if (idx) {
493                 if (idx < 1 || idx > WEP_KEYS)
494                         return -EINVAL;
495                 idx--;
496         } else
497                 idx = ieee->tx_keyidx;
498
499         if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
500                 crypt = &ieee->crypt[idx];
501                 group_key = 1;
502         } else {
503                 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
504                 //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
505                 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
506                         return -EINVAL;
507                 if (ieee->iw_mode == IW_MODE_INFRA)
508                         crypt = &ieee->crypt[idx];
509                 else
510                         return -EINVAL;
511         }
512
513         sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
514         if ((encoding->flags & IW_ENCODE_DISABLED) ||
515             ext->alg == IW_ENCODE_ALG_NONE) {
516                 if (*crypt)
517                         ieee80211_crypt_delayed_deinit(ieee, crypt);
518
519                 for (i = 0; i < WEP_KEYS; i++)
520                         if (ieee->crypt[i] != NULL)
521                                 break;
522
523                 if (i == WEP_KEYS) {
524                         sec.enabled = 0;
525                       //  sec.encrypt = 0;
526                         sec.level = SEC_LEVEL_0;
527                         sec.flags |= SEC_LEVEL;
528                 }
529                 //printk("disabled: flag:%x\n", encoding->flags);
530                 goto done;
531         }
532
533         sec.enabled = 1;
534     //    sec.encrypt = 1;
535
536         switch (ext->alg) {
537         case IW_ENCODE_ALG_WEP:
538                 alg = "WEP";
539                 break;
540         case IW_ENCODE_ALG_TKIP:
541                 alg = "TKIP";
542                 break;
543         case IW_ENCODE_ALG_CCMP:
544                 alg = "CCMP";
545                 break;
546         default:
547                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
548                                    dev->name, ext->alg);
549                 ret = -EINVAL;
550                 goto done;
551         }
552 //      printk("8-09-08-9=====>%s, alg name:%s\n",__func__, alg);
553
554          ops = ieee80211_get_crypto_ops(alg);
555         if (ops == NULL)
556                 ops = ieee80211_get_crypto_ops(alg);
557         if (ops == NULL) {
558                 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
559                                    dev->name, ext->alg);
560                 printk("========>unknown crypto alg %d\n", ext->alg);
561                 ret = -EINVAL;
562                 goto done;
563         }
564
565         if (*crypt == NULL || (*crypt)->ops != ops) {
566                 struct ieee80211_crypt_data *new_crypt;
567
568                 ieee80211_crypt_delayed_deinit(ieee, crypt);
569
570                 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
571                 if (new_crypt == NULL) {
572                         ret = -ENOMEM;
573                         goto done;
574                 }
575                 new_crypt->ops = ops;
576                 if (new_crypt->ops)
577                         new_crypt->priv = new_crypt->ops->init(idx);
578                 if (new_crypt->priv == NULL) {
579                         kfree(new_crypt);
580                         ret = -EINVAL;
581                         goto done;
582                 }
583                 *crypt = new_crypt;
584
585         }
586
587         if (ext->key_len > 0 && (*crypt)->ops->set_key &&
588             (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
589                                    (*crypt)->priv) < 0) {
590                 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
591                 printk("key setting failed\n");
592                 ret = -EINVAL;
593                 goto done;
594         }
595 #if 1
596  //skip_host_crypt:
597         //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
598         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
599                 ieee->tx_keyidx = idx;
600                 sec.active_key = idx;
601                 sec.flags |= SEC_ACTIVE_KEY;
602         }
603
604         if (ext->alg != IW_ENCODE_ALG_NONE) {
605                 memcpy(sec.keys[idx], ext->key, ext->key_len);
606                 sec.key_sizes[idx] = ext->key_len;
607                 sec.flags |= (1 << idx);
608                 if (ext->alg == IW_ENCODE_ALG_WEP) {
609                       //  sec.encode_alg[idx] = SEC_ALG_WEP;
610                         sec.flags |= SEC_LEVEL;
611                         sec.level = SEC_LEVEL_1;
612                 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
613                       //  sec.encode_alg[idx] = SEC_ALG_TKIP;
614                         sec.flags |= SEC_LEVEL;
615                         sec.level = SEC_LEVEL_2;
616                 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
617                        // sec.encode_alg[idx] = SEC_ALG_CCMP;
618                         sec.flags |= SEC_LEVEL;
619                         sec.level = SEC_LEVEL_3;
620                 }
621                 /* Don't set sec level for group keys. */
622                 if (group_key)
623                         sec.flags &= ~SEC_LEVEL;
624         }
625 #endif
626 done:
627         if (ieee->set_security)
628                 ieee->set_security(ieee->dev, &sec);
629
630          if (ieee->reset_on_keychange &&
631             ieee->iw_mode != IW_MODE_INFRA &&
632             ieee->reset_port && ieee->reset_port(dev)) {
633                 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
634                 return -EINVAL;
635         }
636
637         return ret;
638 }
639 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
640                                struct iw_request_info *info,
641                                union iwreq_data *wrqu, char *extra)
642 {
643         struct iw_mlme *mlme = (struct iw_mlme *) extra;
644 //      printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __func__, mlme->cmd);
645 #if 1
646         switch (mlme->cmd) {
647         case IW_MLME_DEAUTH:
648         case IW_MLME_DISASSOC:
649         //      printk("disassoc now\n");
650                 ieee80211_disassociate(ieee);
651                 break;
652          default:
653                 return -EOPNOTSUPP;
654         }
655 #endif
656         return 0;
657 }
658
659 int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
660                                struct iw_request_info *info,
661                                struct iw_param *data, char *extra)
662 {
663 /*
664          struct ieee80211_security sec = {
665                 .flags = SEC_AUTH_MODE,
666         }
667 */
668         //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
669         switch (data->flags & IW_AUTH_INDEX) {
670         case IW_AUTH_WPA_VERSION:
671              /*need to support wpa2 here*/
672                 //printk("wpa version:%x\n", data->value);
673                 break;
674         case IW_AUTH_CIPHER_PAIRWISE:
675         case IW_AUTH_CIPHER_GROUP:
676         case IW_AUTH_KEY_MGMT:
677                 /*
678  *                  * Host AP driver does not use these parameters and allows
679  *                                   * wpa_supplicant to control them internally.
680  *                                                    */
681                 break;
682         case IW_AUTH_TKIP_COUNTERMEASURES:
683                 ieee->tkip_countermeasures = data->value;
684                 break;
685         case IW_AUTH_DROP_UNENCRYPTED:
686                 ieee->drop_unencrypted = data->value;
687                 break;
688
689         case IW_AUTH_80211_AUTH_ALG:
690                 ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
691                 //printk("open_wep:%d\n", ieee->open_wep);
692                 break;
693
694 #if 1
695         case IW_AUTH_WPA_ENABLED:
696                 ieee->wpa_enabled = (data->value)?1:0;
697                 //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
698                 break;
699
700 #endif
701         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
702                 ieee->ieee802_1x = data->value;
703                 break;
704         case IW_AUTH_PRIVACY_INVOKED:
705                 ieee->privacy_invoked = data->value;
706                 break;
707         default:
708                 return -EOPNOTSUPP;
709         }
710         return 0;
711 }
712
713 #if 1
714 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
715 {
716         u8 *buf = NULL;
717
718         if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
719         {
720                 printk("return error out, len:%zu\n", len);
721         return -EINVAL;
722         }
723
724         if (len)
725         {
726                 if (len != ie[1]+2){
727                         printk("len:%zu, ie:%d\n", len, ie[1]);
728                         return -EINVAL;
729                 }
730                 buf = kmalloc(len, GFP_KERNEL);
731                 if (buf == NULL)
732                         return -ENOMEM;
733                 memcpy(buf, ie, len);
734                 kfree(ieee->wpa_ie);
735                 ieee->wpa_ie = buf;
736                 ieee->wpa_ie_len = len;
737         }
738         else{
739                 if (ieee->wpa_ie)
740                 kfree(ieee->wpa_ie);
741                 ieee->wpa_ie = NULL;
742                 ieee->wpa_ie_len = 0;
743         }
744 //      printk("<=====out %s()\n", __func__);
745
746         return 0;
747
748 }
749 #endif