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