480e07f6c4b8305328c5c43192e6cd31e7c2e194
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / vt6656 / iwctl.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * File: iwctl.c
20  *
21  * Purpose:  wireless ext & ioctl functions
22  *
23  * Author: Lyndon Chen
24  *
25  * Date: July 5, 2006
26  *
27  * Functions:
28  *
29  * Revision History:
30  *
31  */
32
33 #include "device.h"
34 #include "ioctl.h"
35 #include "iocmd.h"
36 #include "mac.h"
37 #include "card.h"
38 #include "hostap.h"
39 #include "power.h"
40 #include "rf.h"
41
42 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
43 #include "iowpa.h"
44 #include "wpactl.h"
45 #endif
46
47 #include <net/iw_handler.h>
48
49 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
50 #define SUPPORTED_WIRELESS_EXT                  18
51 #else
52 #define SUPPORTED_WIRELESS_EXT                  17
53 #endif
54
55 static const long frequency_list[] = {
56     2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
57     4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
58     5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
59     5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
60     5700, 5745, 5765, 5785, 5805, 5825
61         };
62
63 static int          msglevel                =MSG_LEVEL_INFO;
64
65 struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
66 {
67         PSDevice pDevice = netdev_priv(dev);
68         long ldBm;
69
70         pDevice->wstats.status = pDevice->eOPMode;
71            if(pDevice->scStatistic.LinkQuality > 100)
72                pDevice->scStatistic.LinkQuality = 100;
73                pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
74         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
75         pDevice->wstats.qual.level = ldBm;
76         pDevice->wstats.qual.noise = 0;
77         pDevice->wstats.qual.updated = 1;
78         pDevice->wstats.discard.nwid = 0;
79         pDevice->wstats.discard.code = 0;
80         pDevice->wstats.discard.fragment = 0;
81         pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr;
82         pDevice->wstats.discard.misc = 0;
83         pDevice->wstats.miss.beacon = 0;
84
85         return &pDevice->wstats;
86 }
87
88 static int iwctl_commit(struct net_device *dev,
89                               struct iw_request_info *info,
90                               void *wrq,
91                               char *extra)
92 {
93     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n");
94
95         return 0;
96 }
97
98 /*
99  * Wireless Handler : get protocol name
100  */
101
102 int iwctl_giwname(struct net_device *dev,
103                          struct iw_request_info *info,
104                          char *wrq,
105                          char *extra)
106 {
107         strcpy(wrq, "802.11-a/b/g");
108         return 0;
109 }
110
111 /*
112  * Wireless Handler : set scan
113  */
114
115 int iwctl_siwscan(struct net_device *dev,
116              struct iw_request_info *info,
117                          struct iw_point *wrq,
118              char *extra)
119 {
120         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
121          PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
122         struct iw_scan_req  *req = (struct iw_scan_req *)extra;
123         BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
124         PWLAN_IE_SSID       pItemSSID=NULL;
125
126   if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
127         return -EINVAL;
128
129     PRINT_K(" SIOCSIWSCAN \n");
130
131 if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
132         // In scanning..
133      PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
134      return -EAGAIN;
135   }
136
137 if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
138 //send scan event to wpa_Supplicant
139   union iwreq_data wrqu;
140  PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
141  memset(&wrqu, 0, sizeof(wrqu));
142  wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
143   return 0;
144 }
145
146         spin_lock_irq(&pDevice->lock);
147
148         BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
149
150 //mike add: active scan OR passive scan OR desire_ssid scan
151  if(wrq->length == sizeof(struct iw_scan_req)) {
152    if (wrq->flags & IW_SCAN_THIS_ESSID)  {                               //desire_ssid scan
153        memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
154        pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
155        pItemSSID->byElementID = WLAN_EID_SSID;
156        memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
157          if (pItemSSID->abySSID[req->essid_len - 1] == '\0') {
158            if(req->essid_len>0)
159                 pItemSSID->len = req->essid_len - 1;
160          }
161         else
162           pItemSSID->len = req->essid_len;
163           pMgmt->eScanType = WMAC_SCAN_PASSIVE;
164          PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
165                                                                                                         ((PWLAN_IE_SSID)abyScanSSID)->len);
166         bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
167         spin_unlock_irq(&pDevice->lock);
168
169         return 0;
170    }
171    else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) {          //passive scan
172        pMgmt->eScanType = WMAC_SCAN_PASSIVE;
173    }
174  }
175  else {           //active scan
176      pMgmt->eScanType = WMAC_SCAN_ACTIVE;
177  }
178
179          pMgmt->eScanType = WMAC_SCAN_PASSIVE;
180         bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
181         spin_unlock_irq(&pDevice->lock);
182
183         return 0;
184 }
185
186 /*
187  * Wireless Handler : get scan results
188  */
189
190 int iwctl_giwscan(struct net_device *dev,
191              struct iw_request_info *info,
192                          struct iw_point *wrq,
193              char *extra)
194 {
195     int ii, jj, kk;
196         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
197     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
198     PKnownBSS           pBSS;
199     PWLAN_IE_SSID       pItemSSID;
200     PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates;
201         char *current_ev = extra;
202         char *end_buf = extra + IW_SCAN_MAX_DATA;
203         char *current_val = NULL;
204         struct iw_event iwe;
205         long ldBm;
206         char buf[MAX_WPA_IE_LEN * 2 + 30];
207
208     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
209
210     if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
211         // In scanning..
212                 return -EAGAIN;
213         }
214         pBSS = &(pMgmt->sBSSList[0]);
215     for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
216                 if (current_ev >= end_buf)
217                         break;
218         pBSS = &(pMgmt->sBSSList[jj]);
219         if (pBSS->bActive) {
220                 //ADD mac address
221                     memset(&iwe, 0, sizeof(iwe));
222                     iwe.cmd = SIOCGIWAP;
223                     iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
224                         memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
225                            current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
226                  //ADD ssid
227                      memset(&iwe, 0, sizeof(iwe));
228                       iwe.cmd = SIOCGIWESSID;
229                       pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
230                        iwe.u.data.length = pItemSSID->len;
231                        iwe.u.data.flags = 1;
232                       current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
233                 //ADD mode
234                     memset(&iwe, 0, sizeof(iwe));
235                     iwe.cmd = SIOCGIWMODE;
236             if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
237                         iwe.u.mode = IW_MODE_INFRA;
238             }
239             else {
240                 iwe.u.mode = IW_MODE_ADHOC;
241                     }
242                 iwe.len = IW_EV_UINT_LEN;
243                       current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
244            //ADD frequency
245             pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
246             pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
247             memset(&iwe, 0, sizeof(iwe));
248                 iwe.cmd = SIOCGIWFREQ;
249                 iwe.u.freq.m = pBSS->uChannel;
250                 iwe.u.freq.e = 0;
251                 iwe.u.freq.i = 0;
252                   current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
253                         {
254                         int f = (int)pBSS->uChannel - 1;
255                         if(f < 0)f = 0;
256                         iwe.u.freq.m = frequency_list[f] * 100000;
257                         iwe.u.freq.e = 1;
258                         }
259                   current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
260                 //ADD quality
261             memset(&iwe, 0, sizeof(iwe));
262                 iwe.cmd = IWEVQUAL;
263                 RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
264                     iwe.u.qual.level = ldBm;
265                 iwe.u.qual.noise = 0;
266
267                         if(-ldBm<50){
268                                 iwe.u.qual.qual = 100;
269                         }else  if(-ldBm > 90) {
270                                  iwe.u.qual.qual = 0;
271                         }else {
272                                 iwe.u.qual.qual=(40-(-ldBm-50))*100/40;
273                         }
274                         iwe.u.qual.updated=7;
275
276                  current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
277         //ADD encryption
278             memset(&iwe, 0, sizeof(iwe));
279             iwe.cmd = SIOCGIWENCODE;
280             iwe.u.data.length = 0;
281             if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
282                 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
283             }else {
284                 iwe.u.data.flags = IW_ENCODE_DISABLED;
285             }
286             current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
287
288             memset(&iwe, 0, sizeof(iwe));
289             iwe.cmd = SIOCGIWRATE;
290                 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
291                 current_val = current_ev + IW_EV_LCP_LEN;
292
293                 for (kk = 0 ; kk < 12 ; kk++) {
294                         if (pSuppRates->abyRates[kk] == 0)
295                                 break;
296                         // Bit rate given in 500 kb/s units (+ 0x80)
297                         iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
298                           current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
299                 }
300                 for (kk = 0 ; kk < 8 ; kk++) {
301                         if (pExtSuppRates->abyRates[kk] == 0)
302                                 break;
303                         // Bit rate given in 500 kb/s units (+ 0x80)
304                         iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
305                          current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
306                 }
307
308                 if((current_val - current_ev) > IW_EV_LCP_LEN)
309                         current_ev = current_val;
310
311             memset(&iwe, 0, sizeof(iwe));
312             iwe.cmd = IWEVCUSTOM;
313             sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
314             iwe.u.data.length = strlen(buf);
315              current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
316
317             if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
318                 memset(&iwe, 0, sizeof(iwe));
319                 iwe.cmd = IWEVGENIE;
320                 iwe.u.data.length = pBSS->wWPALen;
321                 current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE);
322             }
323
324             if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
325                 memset(&iwe, 0, sizeof(iwe));
326                 iwe.cmd = IWEVGENIE;
327                 iwe.u.data.length = pBSS->wRSNLen;
328                 current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE);
329             }
330
331         }
332     }// for
333
334         wrq->length = current_ev - extra;
335         return 0;
336
337 }
338
339
340 /*
341  * Wireless Handler : set frequence or channel
342  */
343
344 int iwctl_siwfreq(struct net_device *dev,
345              struct iw_request_info *info,
346              struct iw_freq *wrq,
347              char *extra)
348 {
349         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
350         int rc = 0;
351
352     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
353
354         // If setting by frequency, convert to a channel
355         if((wrq->e == 1) &&
356            (wrq->m >= (int) 2.412e8) &&
357            (wrq->m <= (int) 2.487e8)) {
358                 int f = wrq->m / 100000;
359                 int c = 0;
360                 while((c < 14) && (f != frequency_list[c]))
361                         c++;
362                 wrq->e = 0;
363                 wrq->m = c + 1;
364         }
365         // Setting by channel number
366         if((wrq->m > 14) || (wrq->e > 0))
367                 rc = -EOPNOTSUPP;
368         else {
369                 int channel = wrq->m;
370                 if((channel < 1) || (channel > 14)) {
371                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
372                         rc = -EINVAL;
373                 } else {
374                           // Yes ! We can set it !!!
375               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
376                           pDevice->uChannel = channel;
377                 }
378         }
379
380         return rc;
381 }
382
383 /*
384  * Wireless Handler : get frequence or channel
385  */
386
387 int iwctl_giwfreq(struct net_device *dev,
388              struct iw_request_info *info,
389              struct iw_freq *wrq,
390              char *extra)
391 {
392         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
393     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
394
395     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
396
397 #ifdef WEXT_USECHANNELS
398         wrq->m = (int)pMgmt->uCurrChannel;
399         wrq->e = 0;
400 #else
401         {
402                 int f = (int)pMgmt->uCurrChannel - 1;
403                 if(f < 0)
404                    f = 0;
405                 wrq->m = frequency_list[f] * 100000;
406                 wrq->e = 1;
407         }
408 #endif
409
410         return 0;
411 }
412
413 /*
414  * Wireless Handler : set operation mode
415  */
416
417 int iwctl_siwmode(struct net_device *dev,
418              struct iw_request_info *info,
419              __u32 *wmode,
420              char *extra)
421 {
422         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
423     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
424     int rc = 0;
425
426     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
427
428     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
429         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
430         return rc;
431     }
432
433         switch(*wmode) {
434
435         case IW_MODE_ADHOC:
436             if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
437             pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
438             if (pDevice->flags & DEVICE_FLAGS_OPENED) {
439                         pDevice->bCommit = TRUE;
440                     }
441                 }
442         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
443                 break;
444         case IW_MODE_AUTO:
445         case IW_MODE_INFRA:
446             if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
447             pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
448             if (pDevice->flags & DEVICE_FLAGS_OPENED) {
449                         pDevice->bCommit = TRUE;
450                     }
451                 }
452         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
453                 break;
454         case IW_MODE_MASTER:
455
456         pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
457                 rc = -EOPNOTSUPP;
458                 break;
459
460             if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
461             pMgmt->eConfigMode = WMAC_CONFIG_AP;
462             if (pDevice->flags & DEVICE_FLAGS_OPENED) {
463                         pDevice->bCommit = TRUE;
464                     }
465                 }
466         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
467                 break;
468
469         case IW_MODE_REPEAT:
470         pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
471                 rc = -EOPNOTSUPP;
472                 break;
473         default:
474                 rc = -EINVAL;
475         }
476
477         return rc;
478 }
479
480 /*
481  * Wireless Handler : get operation mode
482  */
483
484 int iwctl_giwmode(struct net_device *dev,
485              struct iw_request_info *info,
486              __u32 *wmode,
487              char *extra)
488 {
489         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
490     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
491
492
493     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
494         // If not managed, assume it's ad-hoc
495         switch (pMgmt->eConfigMode) {
496         case WMAC_CONFIG_ESS_STA:
497                 *wmode = IW_MODE_INFRA;
498                 break;
499         case WMAC_CONFIG_IBSS_STA:
500         *wmode = IW_MODE_ADHOC;
501                 break;
502         case WMAC_CONFIG_AUTO:
503                 *wmode = IW_MODE_INFRA;
504                 break;
505         case WMAC_CONFIG_AP:
506                 *wmode = IW_MODE_MASTER;
507                 break;
508         default:
509                 *wmode = IW_MODE_ADHOC;
510         }
511
512         return 0;
513 }
514
515
516 /*
517  * Wireless Handler : get capability range
518  */
519
520 int iwctl_giwrange(struct net_device *dev,
521              struct iw_request_info *info,
522              struct iw_point *wrq,
523              char *extra)
524 {
525         struct iw_range *range = (struct iw_range *) extra;
526         int             i,k;
527     BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
528
529     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
530         if (wrq->pointer) {
531                 wrq->length = sizeof(struct iw_range);
532                 memset(range, 0, sizeof(struct iw_range));
533                 range->min_nwid = 0x0000;
534                 range->max_nwid = 0x0000;
535                 range->num_channels = 14;
536                 // Should be based on cap_rid.country to give only
537                 //  what the current card support
538                 k = 0;
539                 for (i = 0; i < 14; i++) {
540                         range->freq[k].i = i + 1; // List index
541                         range->freq[k].m = frequency_list[i] * 100000;
542                         range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
543                 }
544                 range->num_frequency = k;
545                 // Hum... Should put the right values there
546                  range->max_qual.qual = 100;
547                 range->max_qual.level = 0;
548                 range->max_qual.noise = 0;
549                 range->sensitivity = 255;
550
551                 for (i = 0 ; i < 13 ; i++) {
552                         range->bitrate[i] = abySupportedRates[i] * 500000;
553                         if(range->bitrate[i] == 0)
554                                 break;
555                 }
556                 range->num_bitrates = i;
557
558                 // Set an indication of the max TCP throughput
559                 // in bit/s that we can expect using this interface.
560                 //  May be use for QoS stuff... Jean II
561                 if(i > 2)
562                         range->throughput = 5 * 1000 * 1000;
563                 else
564                         range->throughput = 1.5 * 1000 * 1000;
565
566                 range->min_rts = 0;
567                 range->max_rts = 2312;
568                 range->min_frag = 256;
569                 range->max_frag = 2312;
570
571
572             // the encoding capabilities
573             range->num_encoding_sizes = 3;
574             // 64(40) bits WEP
575             range->encoding_size[0] = 5;
576             // 128(104) bits WEP
577             range->encoding_size[1] = 13;
578             // 256 bits for WPA-PSK
579             range->encoding_size[2] = 32;
580             // 4 keys are allowed
581             range->max_encoding_tokens = 4;
582
583             range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
584                     IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
585
586                 range->min_pmp = 0;
587                 range->max_pmp = 1000000;// 1 secs
588                 range->min_pmt = 0;
589                 range->max_pmt = 1000000;// 1 secs
590                 range->pmp_flags = IW_POWER_PERIOD;
591                 range->pmt_flags = IW_POWER_TIMEOUT;
592                 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
593
594                 // Transmit Power - values are in mW
595
596         range->txpower[0] = 100;
597                 range->num_txpower = 1;
598                 range->txpower_capa = IW_TXPOW_MWATT;
599                 range->we_version_source = SUPPORTED_WIRELESS_EXT;
600                 range->we_version_compiled = WIRELESS_EXT;
601                 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
602                 range->retry_flags = IW_RETRY_LIMIT;
603                 range->r_time_flags = IW_RETRY_LIFETIME;
604                 range->min_retry = 1;
605                 range->max_retry = 65535;
606                 range->min_r_time = 1024;
607                 range->max_r_time = 65535 * 1024;
608                 // Experimental measurements - boundary 11/5.5 Mb/s
609                 // Note : with or without the (local->rssi), results
610                 //  are somewhat different. - Jean II
611                 range->avg_qual.qual = 6;
612                 range->avg_qual.level = 176;    // -80 dBm
613                 range->avg_qual.noise = 0;
614         }
615
616
617         return 0;
618 }
619
620
621 /*
622  * Wireless Handler : set ap mac address
623  */
624
625 int iwctl_siwap(struct net_device *dev,
626              struct iw_request_info *info,
627                          struct sockaddr *wrq,
628              char *extra)
629 {
630         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
631     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
632     int rc = 0;
633     BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
634
635    PRINT_K(" SIOCSIWAP \n");
636
637         if (wrq->sa_family != ARPHRD_ETHER)
638                 rc = -EINVAL;
639         else {
640                 memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
641
642         //mike :add
643          if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
644              (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
645               PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
646                return rc;
647          }
648        //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
649        //                  then ignore,because you don't known which one to be connect with??
650         {
651                 unsigned int ii, uSameBssidNum = 0;
652                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
653                      if (pMgmt->sBSSList[ii].bActive &&
654                          !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
655                                              pMgmt->abyDesireBSSID)) {
656                         uSameBssidNum++;
657                      }
658                   }
659              if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
660                  PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
661                 return rc;
662              }
663         }
664
665         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
666                     pDevice->bCommit = TRUE;
667                 }
668         }
669         return rc;
670 }
671
672 /*
673  * Wireless Handler : get ap mac address
674  */
675
676 int iwctl_giwap(struct net_device *dev,
677              struct iw_request_info *info,
678                          struct sockaddr *wrq,
679              char *extra)
680 {
681         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
682     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
683
684
685     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
686
687     memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
688
689  if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
690         memset(wrq->sa_data, 0, 6);
691
692     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
693         memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
694     }
695
696         wrq->sa_family = ARPHRD_ETHER;
697
698         return 0;
699
700 }
701
702
703 /*
704  * Wireless Handler : get ap list
705  */
706
707 int iwctl_giwaplist(struct net_device *dev,
708              struct iw_request_info *info,
709              struct iw_point *wrq,
710              char *extra)
711 {
712         int ii,jj, rc = 0;
713         struct sockaddr sock[IW_MAX_AP];
714         struct iw_quality qual[IW_MAX_AP];
715         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
716     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
717
718
719     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
720         // Only super-user can see AP list
721
722         if (!capable(CAP_NET_ADMIN)) {
723                 rc = -EPERM;
724                 return rc;
725         }
726
727         if (wrq->pointer) {
728
729                 PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
730
731                 for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
732                     pBSS = &(pMgmt->sBSSList[ii]);
733             if (!pBSS->bActive)
734                 continue;
735             if ( jj >= IW_MAX_AP)
736                 break;
737                         memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
738                         sock[jj].sa_family = ARPHRD_ETHER;
739                         qual[jj].level = pBSS->uRSSI;
740                         qual[jj].qual = qual[jj].noise = 0;
741                         qual[jj].updated = 2;
742                         jj++;
743                 }
744
745                 wrq->flags = 1; // Should be define'd
746                 wrq->length = jj;
747                 memcpy(extra, sock, sizeof(struct sockaddr)*jj);
748                 memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
749         }
750
751         return rc;
752 }
753
754
755 /*
756  * Wireless Handler : set essid
757  */
758
759 int iwctl_siwessid(struct net_device *dev,
760              struct iw_request_info *info,
761              struct iw_point *wrq,
762              char *extra)
763 {
764         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
765     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
766     PWLAN_IE_SSID       pItemSSID;
767
768   if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
769         return -EINVAL;
770
771     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
772
773          pDevice->fWPA_Authened = FALSE;
774         // Check if we asked for `any'
775         if(wrq->flags == 0) {
776                 // Just send an empty SSID list
777                 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
778                   memset(pMgmt->abyDesireBSSID, 0xFF,6);
779             PRINT_K("set essid to 'any' \n");
780            #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
781              //Unknown desired AP,so here need not associate??
782                   return 0;
783             #endif
784         } else {
785                 // Set the SSID
786                 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
787         pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
788         pItemSSID->byElementID = WLAN_EID_SSID;
789
790                 memcpy(pItemSSID->abySSID, extra, wrq->length);
791          if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
792            if(wrq->length>0)
793                 pItemSSID->len = wrq->length - 1;
794          }
795         else
796           pItemSSID->len = wrq->length;
797         PRINT_K("set essid to %s \n",pItemSSID->abySSID);
798
799      //mike:need clear desiredBSSID
800      if(pItemSSID->len==0) {
801         memset(pMgmt->abyDesireBSSID, 0xFF,6);
802         return 0;
803      }
804
805 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
806  //Wext wil order another command of siwap to link with desired AP,
807  //so here need not associate??
808   if(pDevice->bWPASuppWextEnabled == TRUE)  {
809         /*******search if  in hidden ssid mode ****/
810         {
811            PKnownBSS       pCurr = NULL;
812            BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
813           unsigned int ii, uSameBssidNum = 0;
814
815           memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
816             pCurr = BSSpSearchBSSList(pDevice,
817                                       NULL,
818                                       abyTmpDesireSSID,
819                                       pDevice->eConfigPHYMode
820                                       );
821
822             if (pCurr == NULL){
823                PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
824               vResetCommandTimer((void *) pDevice);
825               pMgmt->eScanType = WMAC_SCAN_ACTIVE;
826               bScheduleCommand((void *) pDevice,
827                                WLAN_CMD_BSSID_SCAN,
828                                pMgmt->abyDesireSSID);
829               bScheduleCommand((void *) pDevice,
830                                WLAN_CMD_SSID,
831                                pMgmt->abyDesireSSID);
832           }
833          else {  //mike:to find out if that desired SSID is a hidden-ssid AP ,
834                      //         by means of judging if there are two same BSSID exist in list ?
835                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
836                      if (pMgmt->sBSSList[ii].bActive &&
837                          !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
838                                              pCurr->abyBSSID)) {
839                         uSameBssidNum++;
840                      }
841                   }
842              if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
843                  PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
844                  vResetCommandTimer((void *) pDevice);
845                 pMgmt->eScanType = WMAC_SCAN_PASSIVE;          //this scan type,you'll submit scan result!
846                 bScheduleCommand((void *) pDevice,
847                                  WLAN_CMD_BSSID_SCAN,
848                                  pMgmt->abyDesireSSID);
849                 bScheduleCommand((void *) pDevice,
850                                  WLAN_CMD_SSID,
851                                  pMgmt->abyDesireSSID);
852              }
853          }
854         }
855      return 0;
856   }
857              #endif
858
859             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
860         }
861
862     if (pDevice->flags & DEVICE_FLAGS_OPENED) {
863             pDevice->bCommit = TRUE;
864         }
865
866
867         return 0;
868 }
869
870
871 /*
872  * Wireless Handler : get essid
873  */
874
875 int iwctl_giwessid(struct net_device *dev,
876              struct iw_request_info *info,
877              struct iw_point *wrq,
878              char *extra)
879 {
880
881         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
882     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
883         PWLAN_IE_SSID       pItemSSID;
884
885     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
886
887         // Note : if wrq->u.data.flags != 0, we should
888         // get the relevant SSID from the SSID list...
889
890         // Get the current SSID
891     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
892         memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
893         extra[pItemSSID->len] = '\0';
894
895         wrq->length = pItemSSID->len;
896         wrq->flags = 1; // active
897
898         return 0;
899 }
900
901 /*
902  * Wireless Handler : set data rate
903  */
904
905 int iwctl_siwrate(struct net_device *dev,
906              struct iw_request_info *info,
907                          struct iw_param *wrq,
908              char *extra)
909 {
910         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
911     int rc = 0;
912         u8      brate = 0;
913         int     i;
914         BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
915
916
917     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
918     if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
919         rc = -EINVAL;
920         return rc;
921     }
922
923         // First : get a valid bit rate value
924
925         // Which type of value
926         if((wrq->value < 13) &&
927            (wrq->value >= 0)) {
928                 // Setting by rate index
929                 // Find value in the magic rate table
930                 brate = wrq->value;
931         } else {
932                 // Setting by frequency value
933                 u8      normvalue = (u8) (wrq->value/500000);
934
935                 // Check if rate is valid
936                 for (i = 0 ; i < 13 ; i++) {
937                         if(normvalue == abySupportedRates[i]) {
938                                 brate = i;
939                                 break;
940                         }
941                 }
942         }
943         // -1 designed the max rate (mostly auto mode)
944         if(wrq->value == -1) {
945                 // Get the highest available rate
946                 for (i = 0 ; i < 13 ; i++) {
947                         if(abySupportedRates[i] == 0)
948                                 break;
949                 }
950                 if(i != 0)
951                         brate = i - 1;
952
953         }
954         // Check that it is valid
955         // brate is index of abySupportedRates[]
956         if(brate > 13 ) {
957                 rc = -EINVAL;
958                 return rc;
959         }
960
961         // Now, check if we want a fixed or auto value
962         if(wrq->fixed != 0) {
963                 // Fixed mode
964                 // One rate, fixed
965                 pDevice->bFixRate = TRUE;
966         if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
967             pDevice->uConnectionRate = 3;
968         }
969         else {
970             pDevice->uConnectionRate = brate;
971             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
972         }
973
974         }
975         else {
976         pDevice->bFixRate = FALSE;
977         pDevice->uConnectionRate = 13;
978     }
979
980         return rc;
981 }
982
983 /*
984  * Wireless Handler : get data rate
985  */
986
987 int iwctl_giwrate(struct net_device *dev,
988              struct iw_request_info *info,
989              struct iw_param *wrq,
990              char *extra)
991 {
992         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
993     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
994
995     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
996     {
997         BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
998             int brate = 0;
999                 if (pDevice->uConnectionRate < 13) {
1000                 brate = abySupportedRates[pDevice->uConnectionRate];
1001             }else {
1002             if (pDevice->byBBType == BB_TYPE_11B)
1003                     brate = 0x16;
1004             if (pDevice->byBBType == BB_TYPE_11G)
1005                     brate = 0x6C;
1006             if (pDevice->byBBType == BB_TYPE_11A)
1007                     brate = 0x6C;
1008             }
1009
1010             if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1011             if (pDevice->byBBType == BB_TYPE_11B)
1012                     brate = 0x16;
1013             if (pDevice->byBBType == BB_TYPE_11G)
1014                     brate = 0x6C;
1015             if (pDevice->byBBType == BB_TYPE_11A)
1016                     brate = 0x6C;
1017             }
1018                 if (pDevice->uConnectionRate == 13)
1019                 brate = abySupportedRates[pDevice->wCurrentRate];
1020             wrq->value = brate * 500000;
1021             // If more than one rate, set auto
1022             if (pDevice->bFixRate == TRUE)
1023                 wrq->fixed = TRUE;
1024     }
1025
1026
1027         return 0;
1028 }
1029
1030
1031
1032 /*
1033  * Wireless Handler : set rts threshold
1034  */
1035
1036 int iwctl_siwrts(struct net_device *dev,
1037              struct iw_request_info *info,
1038                          struct iw_param *wrq,
1039              char *extra)
1040 {
1041         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1042         int rc = 0;
1043
1044     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
1045
1046         {
1047             int rthr = wrq->value;
1048             if(wrq->disabled)
1049                         rthr = 2312;
1050             if((rthr < 0) || (rthr > 2312)) {
1051                         rc = -EINVAL;
1052         }else {
1053                     pDevice->wRTSThreshold = rthr;
1054             }
1055     }
1056
1057         return 0;
1058 }
1059
1060 /*
1061  * Wireless Handler : get rts
1062  */
1063
1064 int iwctl_giwrts(struct net_device *dev,
1065              struct iw_request_info *info,
1066                          struct iw_param *wrq,
1067              char *extra)
1068 {
1069         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1070
1071     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
1072         wrq->value = pDevice->wRTSThreshold;
1073         wrq->disabled = (wrq->value >= 2312);
1074         wrq->fixed = 1;
1075
1076         return 0;
1077 }
1078
1079 /*
1080  * Wireless Handler : set fragment threshold
1081  */
1082
1083 int iwctl_siwfrag(struct net_device *dev,
1084              struct iw_request_info *info,
1085                          struct iw_param *wrq,
1086              char *extra)
1087 {
1088     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1089     int rc = 0;
1090     int fthr = wrq->value;
1091
1092
1093     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
1094
1095
1096     if (wrq->disabled)
1097                 fthr = 2312;
1098     if((fthr < 256) || (fthr > 2312)) {
1099                 rc = -EINVAL;
1100     }else {
1101                  fthr &= ~0x1;  // Get an even value
1102              pDevice->wFragmentationThreshold = (u16)fthr;
1103     }
1104
1105         return rc;
1106 }
1107
1108 /*
1109  * Wireless Handler : get fragment threshold
1110  */
1111
1112 int iwctl_giwfrag(struct net_device *dev,
1113              struct iw_request_info *info,
1114                          struct iw_param *wrq,
1115              char *extra)
1116 {
1117     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1118
1119     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
1120         wrq->value = pDevice->wFragmentationThreshold;
1121         wrq->disabled = (wrq->value >= 2312);
1122         wrq->fixed = 1;
1123
1124         return 0;
1125 }
1126
1127
1128
1129 /*
1130  * Wireless Handler : set retry threshold
1131  */
1132 int iwctl_siwretry(struct net_device *dev,
1133              struct iw_request_info *info,
1134                          struct iw_param *wrq,
1135              char *extra)
1136 {
1137     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1138     int rc = 0;
1139
1140
1141     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
1142
1143         if (wrq->disabled) {
1144                 rc = -EINVAL;
1145                 return rc;
1146         }
1147
1148         if (wrq->flags & IW_RETRY_LIMIT) {
1149                 if(wrq->flags & IW_RETRY_MAX)
1150                         pDevice->byLongRetryLimit = wrq->value;
1151                 else if (wrq->flags & IW_RETRY_MIN)
1152                         pDevice->byShortRetryLimit = wrq->value;
1153                 else {
1154                         // No modifier : set both
1155                         pDevice->byShortRetryLimit = wrq->value;
1156                         pDevice->byLongRetryLimit = wrq->value;
1157                 }
1158         }
1159         if (wrq->flags & IW_RETRY_LIFETIME) {
1160                 pDevice->wMaxTransmitMSDULifetime = wrq->value;
1161         }
1162
1163
1164         return rc;
1165 }
1166
1167 /*
1168  * Wireless Handler : get retry threshold
1169  */
1170 int iwctl_giwretry(struct net_device *dev,
1171              struct iw_request_info *info,
1172                          struct iw_param *wrq,
1173              char *extra)
1174 {
1175     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1176     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
1177         wrq->disabled = 0;      // Can't be disabled
1178
1179         // Note : by default, display the min retry number
1180         if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1181                 wrq->flags = IW_RETRY_LIFETIME;
1182                 wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
1183         } else if((wrq->flags & IW_RETRY_MAX)) {
1184                 wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1185                 wrq->value = (int)pDevice->byLongRetryLimit;
1186         } else {
1187                 wrq->flags = IW_RETRY_LIMIT;
1188                 wrq->value = (int)pDevice->byShortRetryLimit;
1189                 if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
1190                         wrq->flags |= IW_RETRY_MIN;
1191         }
1192
1193
1194         return 0;
1195 }
1196
1197
1198 /*
1199  * Wireless Handler : set encode mode
1200  */
1201 int iwctl_siwencode(struct net_device *dev,
1202              struct iw_request_info *info,
1203              struct iw_point *wrq,
1204              char *extra)
1205 {
1206     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1207     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1208         DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
1209         int ii,uu, rc = 0;
1210         int index = (wrq->flags & IW_ENCODE_INDEX);
1211
1212
1213     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
1214
1215         // Check the size of the key
1216         if (wrq->length > WLAN_WEP232_KEYLEN) {
1217                 rc = -EINVAL;
1218         return rc;
1219         }
1220
1221         if (dwKeyIndex > WLAN_WEP_NKEYS) {
1222                 rc = -EINVAL;
1223         return rc;
1224     }
1225
1226     if (dwKeyIndex > 0)
1227                 dwKeyIndex--;
1228
1229         // Send the key to the card
1230         if (wrq->length > 0) {
1231
1232         if (wrq->length ==  WLAN_WEP232_KEYLEN) {
1233             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
1234         }
1235         else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
1236             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
1237         }
1238         else if (wrq->length == WLAN_WEP40_KEYLEN) {
1239             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
1240         }
1241         memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
1242         memcpy(pDevice->abyKey, extra, wrq->length);
1243
1244         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
1245         for (ii = 0; ii < wrq->length; ii++) {
1246             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
1247         }
1248
1249         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1250             spin_lock_irq(&pDevice->lock);
1251             KeybSetDefaultKey(  pDevice,
1252                                 &(pDevice->sKey),
1253                                 dwKeyIndex | (1 << 31),
1254                                 wrq->length,
1255                                 NULL,
1256                                 pDevice->abyKey,
1257                                 KEY_CTL_WEP
1258                               );
1259             spin_unlock_irq(&pDevice->lock);
1260         }
1261         pDevice->byKeyIndex = (BYTE)dwKeyIndex;
1262         pDevice->uKeyLength = wrq->length;
1263         pDevice->bTransmitKey = TRUE;
1264         pDevice->bEncryptionEnable = TRUE;
1265         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1266
1267                 // Do we want to just set the transmit key index ?
1268                 if ( index < 4 ) {
1269                     pDevice->byKeyIndex = index;
1270                 } else if (!(wrq->flags & IW_ENCODE_MODE)) {
1271                                 rc = -EINVAL;
1272                                 return rc;
1273             }
1274         }
1275         // Read the flags
1276         if(wrq->flags & IW_ENCODE_DISABLED){
1277
1278         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
1279                 pMgmt->bShareKeyAlgorithm = FALSE;
1280         pDevice->bEncryptionEnable = FALSE;
1281         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1282         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1283             spin_lock_irq(&pDevice->lock);
1284             for (uu = 0; uu < MAX_KEY_TABLE; uu++)
1285                 MACvDisableKeyEntry(pDevice, uu);
1286             spin_unlock_irq(&pDevice->lock);
1287         }
1288         }
1289         if(wrq->flags & IW_ENCODE_RESTRICTED) {
1290         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
1291                 pMgmt->bShareKeyAlgorithm = TRUE;
1292         }
1293         if(wrq->flags & IW_ENCODE_OPEN) {
1294             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
1295                 pMgmt->bShareKeyAlgorithm = FALSE;
1296         }
1297
1298 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1299            memset(pMgmt->abyDesireBSSID, 0xFF,6);
1300 #endif
1301
1302         return rc;
1303 }
1304
1305 int iwctl_giwencode(struct net_device *dev,
1306                         struct iw_request_info *info,
1307                         struct iw_point *wrq,
1308                         char *extra)
1309 {
1310         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1311         PSMgmtObject            pMgmt = &(pDevice->sMgmtObj);
1312         char abyKey[WLAN_WEP232_KEYLEN];
1313
1314         unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
1315         PSKeyItem       pKey = NULL;
1316
1317         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1318
1319         if (index > WLAN_WEP_NKEYS) {
1320                 return  -EINVAL;
1321         }
1322         if(index<1){//get default key
1323                 if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
1324                         index=pDevice->byKeyIndex;
1325                 } else
1326                       index=0;
1327         }else
1328              index--;
1329
1330         memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1331         // Check encryption mode
1332         wrq->flags = IW_ENCODE_NOKEY;
1333         // Is WEP enabled ???
1334         if (pDevice->bEncryptionEnable)
1335                 wrq->flags |=  IW_ENCODE_ENABLED;
1336         else
1337                 wrq->flags |=  IW_ENCODE_DISABLED;
1338
1339         if (pMgmt->bShareKeyAlgorithm)
1340                 wrq->flags |=  IW_ENCODE_RESTRICTED;
1341         else
1342                 wrq->flags |=  IW_ENCODE_OPEN;
1343                 wrq->length=0;
1344
1345         if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
1346                 pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise  key
1347                         if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
1348                            wrq->length = pKey->uKeyLength;
1349                                   memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1350                                   memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1351                            }
1352         }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
1353                         wrq->length = pKey->uKeyLength;
1354                         memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1355                 memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1356         }
1357
1358         wrq->flags |= index+1;
1359
1360         return 0;
1361 }
1362
1363
1364 /*
1365  * Wireless Handler : set power mode
1366  */
1367 int iwctl_siwpower(struct net_device *dev,
1368              struct iw_request_info *info,
1369                          struct iw_param *wrq,
1370              char *extra)
1371 {
1372     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1373     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1374     int rc = 0;
1375
1376     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
1377
1378     if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1379                  rc = -EINVAL;
1380                  return rc;
1381         }
1382
1383         if (wrq->disabled) {
1384                 pDevice->ePSMode = WMAC_POWER_CAM;
1385                 PSvDisablePowerSaving(pDevice);
1386                 return rc;
1387         }
1388         if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1389          pDevice->ePSMode = WMAC_POWER_FAST;
1390          PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
1391
1392         } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
1393              pDevice->ePSMode = WMAC_POWER_FAST;
1394              PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
1395         }
1396         switch (wrq->flags & IW_POWER_MODE) {
1397         case IW_POWER_UNICAST_R:
1398         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
1399                 rc = -EINVAL;
1400                 break;
1401         case IW_POWER_ALL_R:
1402         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
1403                 rc = -EINVAL;
1404         case IW_POWER_ON:
1405         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
1406                 break;
1407         default:
1408                 rc = -EINVAL;
1409         }
1410
1411         return rc;
1412 }
1413
1414 /*
1415  * Wireless Handler : get power mode
1416  */
1417 int iwctl_giwpower(struct net_device *dev,
1418              struct iw_request_info *info,
1419                          struct iw_param *wrq,
1420              char *extra)
1421 {
1422     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1423     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1424     int mode = pDevice->ePSMode;
1425
1426
1427     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
1428
1429
1430         if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
1431             return 0;
1432
1433         if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1434                 wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1435                 wrq->flags = IW_POWER_TIMEOUT;
1436         } else {
1437                 wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1438                 wrq->flags = IW_POWER_PERIOD;
1439         }
1440         wrq->flags |= IW_POWER_ALL_R;
1441
1442         return 0;
1443 }
1444
1445
1446 /*
1447  * Wireless Handler : get Sensitivity
1448  */
1449 int iwctl_giwsens(struct net_device *dev,
1450                          struct iw_request_info *info,
1451                          struct iw_param *wrq,
1452                          char *extra)
1453 {
1454     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1455     long ldBm;
1456
1457     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
1458     if (pDevice->bLinkPass == TRUE) {
1459         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
1460             wrq->value = ldBm;
1461         }
1462         else {
1463             wrq->value = 0;
1464     };
1465         wrq->disabled = (wrq->value == 0);
1466         wrq->fixed = 1;
1467
1468
1469         return 0;
1470 }
1471
1472 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1473
1474 int iwctl_siwauth(struct net_device *dev,
1475                           struct iw_request_info *info,
1476                           struct iw_param *wrq,
1477                           char *extra)
1478 {
1479         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1480         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1481         int ret=0;
1482         static int wpa_version=0;  //must be static to save the last value,einsn liu
1483         static int pairwise=0;
1484
1485     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1486         switch (wrq->flags & IW_AUTH_INDEX) {
1487         case IW_AUTH_WPA_VERSION:
1488                 wpa_version = wrq->value;
1489                 if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
1490                        PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
1491                 }
1492                 else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
1493                           PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
1494                 }
1495                 else {
1496                           PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
1497                 }
1498                 break;
1499         case IW_AUTH_CIPHER_PAIRWISE:
1500                 pairwise = wrq->value;
1501                    PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
1502                 if(pairwise == IW_AUTH_CIPHER_CCMP){
1503                         pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1504                 }else if(pairwise == IW_AUTH_CIPHER_TKIP){
1505                         pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1506                 } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
1507                            pairwise == IW_AUTH_CIPHER_WEP104) {
1508                         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1509                 }else if(pairwise == IW_AUTH_CIPHER_NONE){
1510                         //do nothing,einsn liu
1511                 }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1512
1513                 break;
1514         case IW_AUTH_CIPHER_GROUP:
1515                  PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
1516                 if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
1517                         break;
1518                 if(pairwise == IW_AUTH_CIPHER_NONE){
1519                         if(wrq->value == IW_AUTH_CIPHER_CCMP){
1520                                 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1521                         }else {
1522                                 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1523                         }
1524                 }
1525                 break;
1526         case IW_AUTH_KEY_MGMT:
1527                     PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
1528                 if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
1529                         if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1530                                 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1531                         else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
1532                 }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
1533                         if(wrq->value == 0){
1534                                 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
1535                         }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1536                                 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
1537                         else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
1538                 }
1539
1540                 break;
1541         case IW_AUTH_TKIP_COUNTERMEASURES:
1542                 break;          /* FIXME */
1543         case IW_AUTH_DROP_UNENCRYPTED:
1544                 break;
1545         case IW_AUTH_80211_AUTH_ALG:
1546                  PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
1547                 if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
1548                         pMgmt->bShareKeyAlgorithm=FALSE;
1549                 }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
1550                         pMgmt->bShareKeyAlgorithm=TRUE;
1551                 }
1552                 break;
1553         case IW_AUTH_WPA_ENABLED:
1554                 break;
1555         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1556                 break;
1557         case IW_AUTH_ROAMING_CONTROL:
1558                 ret = -EOPNOTSUPP;
1559                 break;
1560         case IW_AUTH_PRIVACY_INVOKED:
1561                 pDevice->bEncryptionEnable = !!wrq->value;
1562                 if(pDevice->bEncryptionEnable == FALSE){
1563                         wpa_version = 0;
1564                         pairwise = 0;
1565                         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1566                         pMgmt->bShareKeyAlgorithm = FALSE;
1567                         pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
1568                          PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
1569                 }
1570
1571                 break;
1572         default:
1573                 ret = -EOPNOTSUPP;
1574                 break;
1575         }
1576    return ret;
1577 }
1578
1579
1580 int iwctl_giwauth(struct net_device *dev,
1581                           struct iw_request_info *info,
1582                           struct iw_param *wrq,
1583                           char *extra)
1584 {
1585         return -EOPNOTSUPP;
1586 }
1587
1588
1589
1590 int iwctl_siwgenie(struct net_device *dev,
1591                           struct iw_request_info *info,
1592                           struct iw_point *wrq,
1593                           char *extra)
1594 {
1595         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1596         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1597         int ret=0;
1598
1599         if(wrq->length){
1600                 if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
1601                         ret = -EINVAL;
1602                         goto out;
1603                 }
1604                 if(wrq->length > MAX_WPA_IE_LEN){
1605                         ret = -ENOMEM;
1606                         goto out;
1607                 }
1608                 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1609                 if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
1610                         ret = -EFAULT;
1611                         goto out;
1612                 }
1613                 pMgmt->wWPAIELen = wrq->length;
1614         }else {
1615                 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1616                 pMgmt->wWPAIELen = 0;
1617         }
1618
1619         out://not completely ...not necessary in wpa_supplicant 0.5.8
1620         return ret;
1621 }
1622
1623 int iwctl_giwgenie(struct net_device *dev,
1624                           struct iw_request_info *info,
1625                           struct iw_point *wrq,
1626                           char *extra)
1627 {
1628         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1629         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1630         int ret=0;
1631         int space = wrq->length;
1632
1633         wrq->length = 0;
1634         if(pMgmt->wWPAIELen > 0){
1635                 wrq->length = pMgmt->wWPAIELen;
1636                 if(pMgmt->wWPAIELen <= space){
1637                         if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
1638                                 ret = -EFAULT;
1639                         }
1640                 }else
1641                         ret = -E2BIG;
1642         }
1643
1644         return ret;
1645 }
1646
1647
1648 int iwctl_siwencodeext(struct net_device *dev,
1649              struct iw_request_info *info,
1650              struct iw_point *wrq,
1651              char *extra)
1652 {
1653     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1654     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1655         struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1656     struct viawget_wpa_param *param=NULL;
1657 //original member
1658     wpa_alg alg_name;
1659     u8  addr[6];
1660     int key_idx, set_tx=0;
1661     u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
1662     u8 key[64];
1663     size_t seq_len=0,key_len=0;
1664     u8 *buf;
1665     size_t blen;
1666     u8 key_array[64];
1667     int ret=0;
1668
1669 PRINT_K("SIOCSIWENCODEEXT...... \n");
1670
1671 blen = sizeof(*param);
1672 buf = kmalloc((int)blen, (int)GFP_KERNEL);
1673 if (buf == NULL)
1674     return -ENOMEM;
1675 memset(buf, 0, blen);
1676 param = (struct viawget_wpa_param *) buf;
1677
1678 //recover alg_name
1679 switch (ext->alg) {
1680     case IW_ENCODE_ALG_NONE:
1681                   alg_name = WPA_ALG_NONE;
1682                 break;
1683     case IW_ENCODE_ALG_WEP:
1684                   alg_name = WPA_ALG_WEP;
1685                 break;
1686     case IW_ENCODE_ALG_TKIP:
1687                   alg_name = WPA_ALG_TKIP;
1688                 break;
1689     case IW_ENCODE_ALG_CCMP:
1690                   alg_name = WPA_ALG_CCMP;
1691                 break;
1692     default:
1693                 PRINT_K("Unknown alg = %d\n",ext->alg);
1694                 ret= -ENOMEM;
1695                 goto error;
1696                 }
1697 //recover addr
1698  memcpy(addr, ext->addr.sa_data, ETH_ALEN);
1699 //recover key_idx
1700   key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
1701 //recover set_tx
1702 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1703    set_tx = 1;
1704 //recover seq,seq_len
1705         if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1706    seq_len=IW_ENCODE_SEQ_MAX_SIZE;
1707    memcpy(seq, ext->rx_seq, seq_len);
1708                 }
1709 //recover key,key_len
1710 if(ext->key_len) {
1711   key_len=ext->key_len;
1712   memcpy(key, &ext->key[0], key_len);
1713         }
1714
1715 memset(key_array, 0, 64);
1716 if ( key_len > 0) {
1717      memcpy(key_array, key, key_len);
1718     if (key_len == 32) {
1719           // notice ! the oder
1720           memcpy(&key_array[16], &key[24], 8);
1721           memcpy(&key_array[24], &key[16], 8);
1722         }
1723         }
1724
1725 /**************Translate iw_encode_ext to viawget_wpa_param****************/
1726 memcpy(param->addr, addr, ETH_ALEN);
1727 param->u.wpa_key.alg_name = (int)alg_name;
1728 param->u.wpa_key.set_tx = set_tx;
1729 param->u.wpa_key.key_index = key_idx;
1730 param->u.wpa_key.key_len = key_len;
1731 param->u.wpa_key.key = (u8 *)key_array;
1732 param->u.wpa_key.seq = (u8 *)seq;
1733 param->u.wpa_key.seq_len = seq_len;
1734
1735 //****set if current action is Network Manager count??
1736 //****this method is so foolish,but there is no other way???
1737 if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
1738    if(param->u.wpa_key.key_index ==0) {
1739      pDevice->bwextstep0 = TRUE;
1740     }
1741    if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
1742      pDevice->bwextstep0 = FALSE;
1743      pDevice->bwextstep1 = TRUE;
1744     }
1745    if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
1746      pDevice->bwextstep1 = FALSE;
1747      pDevice->bwextstep2 = TRUE;
1748         }
1749    if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
1750      pDevice->bwextstep2 = FALSE;
1751      pDevice->bwextstep3 = TRUE;
1752         }
1753                  }
1754 if(pDevice->bwextstep3 == TRUE) {
1755     PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
1756      pDevice->bwextstep0 = FALSE;
1757      pDevice->bwextstep1 = FALSE;
1758      pDevice->bwextstep2 = FALSE;
1759      pDevice->bwextstep3 = FALSE;
1760      pDevice->bWPASuppWextEnabled = TRUE;
1761      memset(pMgmt->abyDesireBSSID, 0xFF,6);
1762      KeyvInitTable(pDevice,&pDevice->sKey);
1763                  }
1764 //******
1765
1766                 spin_lock_irq(&pDevice->lock);
1767  ret = wpa_set_keys(pDevice, param, TRUE);
1768                 spin_unlock_irq(&pDevice->lock);
1769
1770 error:
1771 kfree(param);
1772         return ret;
1773 }
1774
1775
1776
1777 int iwctl_giwencodeext(struct net_device *dev,
1778              struct iw_request_info *info,
1779              struct iw_point *wrq,
1780              char *extra)
1781 {
1782                 return -EOPNOTSUPP;
1783 }
1784
1785 int iwctl_siwmlme(struct net_device *dev,
1786                                 struct iw_request_info * info,
1787                                 struct iw_point *wrq,
1788                                 char *extra)
1789 {
1790         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1791         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1792         struct iw_mlme *mlme = (struct iw_mlme *)extra;
1793         int ret = 0;
1794
1795         if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
1796                 ret = -EINVAL;
1797                 return ret;
1798         }
1799         switch(mlme->cmd){
1800         case IW_MLME_DEAUTH:
1801         case IW_MLME_DISASSOC:
1802                 if(pDevice->bLinkPass == TRUE){
1803                   PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
1804                   bScheduleCommand((void *) pDevice,
1805                                    WLAN_CMD_DISASSOCIATE,
1806                                    NULL);
1807                 }
1808                 break;
1809         default:
1810                 ret = -EOPNOTSUPP;
1811         }
1812
1813         return ret;
1814
1815 }
1816
1817 #endif
1818
1819 static const iw_handler         iwctl_handler[] =
1820 {
1821         (iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
1822         (iw_handler) NULL,      // SIOCGIWNAME
1823         (iw_handler) NULL,                              // SIOCSIWNWID
1824         (iw_handler) NULL,                              // SIOCGIWNWID
1825         (iw_handler) NULL,              // SIOCSIWFREQ
1826         (iw_handler) NULL,              // SIOCGIWFREQ
1827         (iw_handler) NULL,              // SIOCSIWMODE
1828         (iw_handler) NULL,              // SIOCGIWMODE
1829         (iw_handler) NULL,                      // SIOCSIWSENS
1830         (iw_handler) NULL,                      // SIOCGIWSENS
1831         (iw_handler) NULL,                      // SIOCSIWRANGE
1832         (iw_handler) iwctl_giwrange,            // SIOCGIWRANGE
1833         (iw_handler) NULL,                          // SIOCSIWPRIV
1834         (iw_handler) NULL,                      // SIOCGIWPRIV
1835         (iw_handler) NULL,                      // SIOCSIWSTATS
1836         (iw_handler) NULL,                  // SIOCGIWSTATS
1837     (iw_handler) NULL,                  // SIOCSIWSPY
1838         (iw_handler) NULL,                          // SIOCGIWSPY
1839         (iw_handler) NULL,                                  // -- hole --
1840         (iw_handler) NULL,                                  // -- hole --
1841         (iw_handler) NULL,                  // SIOCSIWAP
1842         (iw_handler) NULL,                  // SIOCGIWAP
1843         (iw_handler) NULL,                                  // -- hole -- 0x16
1844         (iw_handler) NULL,       // SIOCGIWAPLIST
1845         (iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
1846         (iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
1847         (iw_handler) NULL,              // SIOCSIWESSID
1848         (iw_handler) NULL,              // SIOCGIWESSID
1849         (iw_handler) NULL,              // SIOCSIWNICKN
1850         (iw_handler) NULL,              // SIOCGIWNICKN
1851         (iw_handler) NULL,              // -- hole --
1852         (iw_handler) NULL,              // -- hole --
1853         (iw_handler) NULL,              // SIOCSIWRATE 0x20
1854         (iw_handler) NULL,              // SIOCGIWRATE
1855         (iw_handler) NULL,              // SIOCSIWRTS
1856         (iw_handler) NULL,              // SIOCGIWRTS
1857         (iw_handler) NULL,              // SIOCSIWFRAG
1858         (iw_handler) NULL,              // SIOCGIWFRAG
1859         (iw_handler) NULL,              // SIOCSIWTXPOW
1860         (iw_handler) NULL,              // SIOCGIWTXPOW
1861         (iw_handler) NULL,              // SIOCSIWRETRY
1862         (iw_handler) NULL,              // SIOCGIWRETRY
1863         (iw_handler) NULL,              // SIOCSIWENCODE
1864         (iw_handler) NULL,              // SIOCGIWENCODE
1865         (iw_handler) NULL,              // SIOCSIWPOWER
1866         (iw_handler) NULL,              // SIOCGIWPOWER
1867         (iw_handler) NULL,                      // -- hole --
1868         (iw_handler) NULL,                      // -- hole --
1869         (iw_handler) NULL,    // SIOCSIWGENIE
1870         (iw_handler) NULL,    // SIOCGIWGENIE
1871         (iw_handler) NULL,              // SIOCSIWAUTH
1872         (iw_handler) NULL,              // SIOCGIWAUTH
1873         (iw_handler) NULL,              // SIOCSIWENCODEEXT
1874         (iw_handler) NULL,              // SIOCGIWENCODEEXT
1875         (iw_handler) NULL,                              // SIOCSIWPMKSA
1876         (iw_handler) NULL,                              // -- hole --
1877 };
1878
1879
1880 static const iw_handler         iwctl_private_handler[] =
1881 {
1882         NULL,                           // SIOCIWFIRSTPRIV
1883 };
1884
1885
1886 struct iw_priv_args iwctl_private_args[] = {
1887 { IOCTL_CMD_SET,
1888   IW_PRIV_TYPE_CHAR | 1024, 0,
1889   "set"},
1890 };
1891
1892
1893
1894 const struct iw_handler_def     iwctl_handler_def =
1895 {
1896         .get_wireless_stats = &iwctl_get_wireless_stats,
1897         .num_standard   = sizeof(iwctl_handler)/sizeof(iw_handler),
1898         .num_private    = 0,
1899         .num_private_args = 0,
1900         .standard       = (iw_handler *) iwctl_handler,
1901         .private        = NULL,
1902         .private_args   = NULL,
1903 };