KVM: x86: update KVM_SAVE_MSRS_BEGIN to correct value
[cascardo/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 void 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
503
504 /*
505  * Wireless Handler : get capability range
506  */
507
508 void iwctl_giwrange(struct net_device *dev,
509              struct iw_request_info *info,
510              struct iw_point *wrq,
511              char *extra)
512 {
513         struct iw_range *range = (struct iw_range *) extra;
514         int             i,k;
515     BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
516
517     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
518         if (wrq->pointer) {
519                 wrq->length = sizeof(struct iw_range);
520                 memset(range, 0, sizeof(struct iw_range));
521                 range->min_nwid = 0x0000;
522                 range->max_nwid = 0x0000;
523                 range->num_channels = 14;
524                 // Should be based on cap_rid.country to give only
525                 //  what the current card support
526                 k = 0;
527                 for (i = 0; i < 14; i++) {
528                         range->freq[k].i = i + 1; // List index
529                         range->freq[k].m = frequency_list[i] * 100000;
530                         range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
531                 }
532                 range->num_frequency = k;
533                 // Hum... Should put the right values there
534                  range->max_qual.qual = 100;
535                 range->max_qual.level = 0;
536                 range->max_qual.noise = 0;
537                 range->sensitivity = 255;
538
539                 for (i = 0 ; i < 13 ; i++) {
540                         range->bitrate[i] = abySupportedRates[i] * 500000;
541                         if(range->bitrate[i] == 0)
542                                 break;
543                 }
544                 range->num_bitrates = i;
545
546                 // Set an indication of the max TCP throughput
547                 // in bit/s that we can expect using this interface.
548                 //  May be use for QoS stuff... Jean II
549                 if(i > 2)
550                         range->throughput = 5 * 1000 * 1000;
551                 else
552                         range->throughput = 1.5 * 1000 * 1000;
553
554                 range->min_rts = 0;
555                 range->max_rts = 2312;
556                 range->min_frag = 256;
557                 range->max_frag = 2312;
558
559
560             // the encoding capabilities
561             range->num_encoding_sizes = 3;
562             // 64(40) bits WEP
563             range->encoding_size[0] = 5;
564             // 128(104) bits WEP
565             range->encoding_size[1] = 13;
566             // 256 bits for WPA-PSK
567             range->encoding_size[2] = 32;
568             // 4 keys are allowed
569             range->max_encoding_tokens = 4;
570
571             range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
572                     IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
573
574                 range->min_pmp = 0;
575                 range->max_pmp = 1000000;// 1 secs
576                 range->min_pmt = 0;
577                 range->max_pmt = 1000000;// 1 secs
578                 range->pmp_flags = IW_POWER_PERIOD;
579                 range->pmt_flags = IW_POWER_TIMEOUT;
580                 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
581
582                 // Transmit Power - values are in mW
583
584         range->txpower[0] = 100;
585                 range->num_txpower = 1;
586                 range->txpower_capa = IW_TXPOW_MWATT;
587                 range->we_version_source = SUPPORTED_WIRELESS_EXT;
588                 range->we_version_compiled = WIRELESS_EXT;
589                 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
590                 range->retry_flags = IW_RETRY_LIMIT;
591                 range->r_time_flags = IW_RETRY_LIFETIME;
592                 range->min_retry = 1;
593                 range->max_retry = 65535;
594                 range->min_r_time = 1024;
595                 range->max_r_time = 65535 * 1024;
596                 // Experimental measurements - boundary 11/5.5 Mb/s
597                 // Note : with or without the (local->rssi), results
598                 //  are somewhat different. - Jean II
599                 range->avg_qual.qual = 6;
600                 range->avg_qual.level = 176;    // -80 dBm
601                 range->avg_qual.noise = 0;
602         }
603 }
604
605
606 /*
607  * Wireless Handler : set ap mac address
608  */
609
610 int iwctl_siwap(struct net_device *dev,
611              struct iw_request_info *info,
612                          struct sockaddr *wrq,
613              char *extra)
614 {
615         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
616     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
617     int rc = 0;
618     BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
619
620    PRINT_K(" SIOCSIWAP \n");
621
622         if (wrq->sa_family != ARPHRD_ETHER)
623                 rc = -EINVAL;
624         else {
625                 memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
626
627         //mike :add
628          if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
629              (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
630               PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
631                return rc;
632          }
633        //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
634        //                  then ignore,because you don't known which one to be connect with??
635         {
636                 unsigned int ii, uSameBssidNum = 0;
637                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
638                      if (pMgmt->sBSSList[ii].bActive &&
639                          !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
640                                              pMgmt->abyDesireBSSID)) {
641                         uSameBssidNum++;
642                      }
643                   }
644              if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
645                  PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
646                 return rc;
647              }
648         }
649
650         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
651                     pDevice->bCommit = TRUE;
652                 }
653         }
654         return rc;
655 }
656
657 /*
658  * Wireless Handler : get ap mac address
659  */
660
661 int iwctl_giwap(struct net_device *dev,
662              struct iw_request_info *info,
663                          struct sockaddr *wrq,
664              char *extra)
665 {
666         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
667     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
668
669
670     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
671
672     memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
673
674  if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
675         memset(wrq->sa_data, 0, 6);
676
677     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
678         memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
679     }
680
681         wrq->sa_family = ARPHRD_ETHER;
682
683         return 0;
684
685 }
686
687
688 /*
689  * Wireless Handler : get ap list
690  */
691
692 int iwctl_giwaplist(struct net_device *dev,
693              struct iw_request_info *info,
694              struct iw_point *wrq,
695              char *extra)
696 {
697         int ii,jj, rc = 0;
698         struct sockaddr sock[IW_MAX_AP];
699         struct iw_quality qual[IW_MAX_AP];
700         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
701     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
702
703
704     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
705         // Only super-user can see AP list
706
707         if (!capable(CAP_NET_ADMIN)) {
708                 rc = -EPERM;
709                 return rc;
710         }
711
712         if (wrq->pointer) {
713
714                 PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
715
716                 for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
717                     pBSS = &(pMgmt->sBSSList[ii]);
718             if (!pBSS->bActive)
719                 continue;
720             if ( jj >= IW_MAX_AP)
721                 break;
722                         memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
723                         sock[jj].sa_family = ARPHRD_ETHER;
724                         qual[jj].level = pBSS->uRSSI;
725                         qual[jj].qual = qual[jj].noise = 0;
726                         qual[jj].updated = 2;
727                         jj++;
728                 }
729
730                 wrq->flags = 1; // Should be define'd
731                 wrq->length = jj;
732                 memcpy(extra, sock, sizeof(struct sockaddr)*jj);
733                 memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
734         }
735
736         return rc;
737 }
738
739
740 /*
741  * Wireless Handler : set essid
742  */
743
744 int iwctl_siwessid(struct net_device *dev,
745              struct iw_request_info *info,
746              struct iw_point *wrq,
747              char *extra)
748 {
749         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
750     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
751     PWLAN_IE_SSID       pItemSSID;
752
753   if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
754         return -EINVAL;
755
756     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
757
758          pDevice->fWPA_Authened = FALSE;
759         // Check if we asked for `any'
760         if(wrq->flags == 0) {
761                 // Just send an empty SSID list
762                 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
763                   memset(pMgmt->abyDesireBSSID, 0xFF,6);
764             PRINT_K("set essid to 'any' \n");
765            #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
766              //Unknown desired AP,so here need not associate??
767                   return 0;
768             #endif
769         } else {
770                 // Set the SSID
771                 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
772         pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
773         pItemSSID->byElementID = WLAN_EID_SSID;
774
775                 memcpy(pItemSSID->abySSID, extra, wrq->length);
776          if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
777            if(wrq->length>0)
778                 pItemSSID->len = wrq->length - 1;
779          }
780         else
781           pItemSSID->len = wrq->length;
782         PRINT_K("set essid to %s \n",pItemSSID->abySSID);
783
784      //mike:need clear desiredBSSID
785      if(pItemSSID->len==0) {
786         memset(pMgmt->abyDesireBSSID, 0xFF,6);
787         return 0;
788      }
789
790 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
791  //Wext wil order another command of siwap to link with desired AP,
792  //so here need not associate??
793   if(pDevice->bWPASuppWextEnabled == TRUE)  {
794         /*******search if  in hidden ssid mode ****/
795         {
796            PKnownBSS       pCurr = NULL;
797            BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
798           unsigned int ii, uSameBssidNum = 0;
799
800           memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
801             pCurr = BSSpSearchBSSList(pDevice,
802                                       NULL,
803                                       abyTmpDesireSSID,
804                                       pDevice->eConfigPHYMode
805                                       );
806
807             if (pCurr == NULL){
808                PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
809               vResetCommandTimer((void *) pDevice);
810               pMgmt->eScanType = WMAC_SCAN_ACTIVE;
811               bScheduleCommand((void *) pDevice,
812                                WLAN_CMD_BSSID_SCAN,
813                                pMgmt->abyDesireSSID);
814               bScheduleCommand((void *) pDevice,
815                                WLAN_CMD_SSID,
816                                pMgmt->abyDesireSSID);
817           }
818          else {  //mike:to find out if that desired SSID is a hidden-ssid AP ,
819                      //         by means of judging if there are two same BSSID exist in list ?
820                   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
821                      if (pMgmt->sBSSList[ii].bActive &&
822                          !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
823                                              pCurr->abyBSSID)) {
824                         uSameBssidNum++;
825                      }
826                   }
827              if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
828                  PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
829                  vResetCommandTimer((void *) pDevice);
830                 pMgmt->eScanType = WMAC_SCAN_PASSIVE;          //this scan type,you'll submit scan result!
831                 bScheduleCommand((void *) pDevice,
832                                  WLAN_CMD_BSSID_SCAN,
833                                  pMgmt->abyDesireSSID);
834                 bScheduleCommand((void *) pDevice,
835                                  WLAN_CMD_SSID,
836                                  pMgmt->abyDesireSSID);
837              }
838          }
839         }
840      return 0;
841   }
842              #endif
843
844             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
845         }
846
847     if (pDevice->flags & DEVICE_FLAGS_OPENED) {
848             pDevice->bCommit = TRUE;
849         }
850
851
852         return 0;
853 }
854
855
856 /*
857  * Wireless Handler : get essid
858  */
859 void iwctl_giwessid(struct net_device *dev,
860              struct iw_request_info *info,
861              struct iw_point *wrq,
862              char *extra)
863 {
864
865         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
866     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
867         PWLAN_IE_SSID       pItemSSID;
868
869     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
870
871         // Note : if wrq->u.data.flags != 0, we should
872         // get the relevant SSID from the SSID list...
873
874         // Get the current SSID
875     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
876         memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
877         extra[pItemSSID->len] = '\0';
878
879         wrq->length = pItemSSID->len;
880         wrq->flags = 1; // active
881 }
882
883 /*
884  * Wireless Handler : set data rate
885  */
886
887 int iwctl_siwrate(struct net_device *dev,
888              struct iw_request_info *info,
889                          struct iw_param *wrq,
890              char *extra)
891 {
892         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
893     int rc = 0;
894         u8      brate = 0;
895         int     i;
896         BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
897
898
899     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
900     if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
901         rc = -EINVAL;
902         return rc;
903     }
904
905         // First : get a valid bit rate value
906
907         // Which type of value
908         if((wrq->value < 13) &&
909            (wrq->value >= 0)) {
910                 // Setting by rate index
911                 // Find value in the magic rate table
912                 brate = wrq->value;
913         } else {
914                 // Setting by frequency value
915                 u8      normvalue = (u8) (wrq->value/500000);
916
917                 // Check if rate is valid
918                 for (i = 0 ; i < 13 ; i++) {
919                         if(normvalue == abySupportedRates[i]) {
920                                 brate = i;
921                                 break;
922                         }
923                 }
924         }
925         // -1 designed the max rate (mostly auto mode)
926         if(wrq->value == -1) {
927                 // Get the highest available rate
928                 for (i = 0 ; i < 13 ; i++) {
929                         if(abySupportedRates[i] == 0)
930                                 break;
931                 }
932                 if(i != 0)
933                         brate = i - 1;
934
935         }
936         // Check that it is valid
937         // brate is index of abySupportedRates[]
938         if(brate > 13 ) {
939                 rc = -EINVAL;
940                 return rc;
941         }
942
943         // Now, check if we want a fixed or auto value
944         if(wrq->fixed != 0) {
945                 // Fixed mode
946                 // One rate, fixed
947                 pDevice->bFixRate = TRUE;
948         if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
949             pDevice->uConnectionRate = 3;
950         }
951         else {
952             pDevice->uConnectionRate = brate;
953             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
954         }
955
956         }
957         else {
958         pDevice->bFixRate = FALSE;
959         pDevice->uConnectionRate = 13;
960     }
961
962         return rc;
963 }
964
965 /*
966  * Wireless Handler : get data rate
967  */
968 void iwctl_giwrate(struct net_device *dev,
969              struct iw_request_info *info,
970              struct iw_param *wrq,
971              char *extra)
972 {
973         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
974     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
975
976     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
977     {
978         BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
979             int brate = 0;
980                 if (pDevice->uConnectionRate < 13) {
981                 brate = abySupportedRates[pDevice->uConnectionRate];
982             }else {
983             if (pDevice->byBBType == BB_TYPE_11B)
984                     brate = 0x16;
985             if (pDevice->byBBType == BB_TYPE_11G)
986                     brate = 0x6C;
987             if (pDevice->byBBType == BB_TYPE_11A)
988                     brate = 0x6C;
989             }
990
991             if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
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                 if (pDevice->uConnectionRate == 13)
1000                 brate = abySupportedRates[pDevice->wCurrentRate];
1001             wrq->value = brate * 500000;
1002             // If more than one rate, set auto
1003             if (pDevice->bFixRate == TRUE)
1004                 wrq->fixed = TRUE;
1005     }
1006 }
1007
1008
1009
1010 /*
1011  * Wireless Handler : set rts threshold
1012  */
1013 int iwctl_siwrts(struct net_device *dev,
1014                  struct iw_param *wrq)
1015 {
1016         PSDevice pDevice = (PSDevice)netdev_priv(dev);
1017
1018         if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
1019                 return -EINVAL;
1020
1021         else if (wrq->disabled)
1022                 pDevice->wRTSThreshold = 2312;
1023
1024         else
1025                 pDevice->wRTSThreshold = wrq->value;
1026
1027         return 0;
1028 }
1029
1030 /*
1031  * Wireless Handler : get rts
1032  */
1033
1034 int iwctl_giwrts(struct net_device *dev,
1035              struct iw_request_info *info,
1036                          struct iw_param *wrq,
1037              char *extra)
1038 {
1039         PSDevice                pDevice = (PSDevice)netdev_priv(dev);
1040
1041     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
1042         wrq->value = pDevice->wRTSThreshold;
1043         wrq->disabled = (wrq->value >= 2312);
1044         wrq->fixed = 1;
1045
1046         return 0;
1047 }
1048
1049 /*
1050  * Wireless Handler : set fragment threshold
1051  */
1052
1053 int iwctl_siwfrag(struct net_device *dev,
1054              struct iw_request_info *info,
1055                          struct iw_param *wrq,
1056              char *extra)
1057 {
1058     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1059     int rc = 0;
1060     int fthr = wrq->value;
1061
1062
1063     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
1064
1065
1066     if (wrq->disabled)
1067                 fthr = 2312;
1068     if((fthr < 256) || (fthr > 2312)) {
1069                 rc = -EINVAL;
1070     }else {
1071                  fthr &= ~0x1;  // Get an even value
1072              pDevice->wFragmentationThreshold = (u16)fthr;
1073     }
1074
1075         return rc;
1076 }
1077
1078 /*
1079  * Wireless Handler : get fragment threshold
1080  */
1081
1082 int iwctl_giwfrag(struct net_device *dev,
1083              struct iw_request_info *info,
1084                          struct iw_param *wrq,
1085              char *extra)
1086 {
1087     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1088
1089     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
1090         wrq->value = pDevice->wFragmentationThreshold;
1091         wrq->disabled = (wrq->value >= 2312);
1092         wrq->fixed = 1;
1093
1094         return 0;
1095 }
1096
1097
1098
1099 /*
1100  * Wireless Handler : set retry threshold
1101  */
1102 int iwctl_siwretry(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     int rc = 0;
1109
1110
1111     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
1112
1113         if (wrq->disabled) {
1114                 rc = -EINVAL;
1115                 return rc;
1116         }
1117
1118         if (wrq->flags & IW_RETRY_LIMIT) {
1119                 if(wrq->flags & IW_RETRY_MAX)
1120                         pDevice->byLongRetryLimit = wrq->value;
1121                 else if (wrq->flags & IW_RETRY_MIN)
1122                         pDevice->byShortRetryLimit = wrq->value;
1123                 else {
1124                         // No modifier : set both
1125                         pDevice->byShortRetryLimit = wrq->value;
1126                         pDevice->byLongRetryLimit = wrq->value;
1127                 }
1128         }
1129         if (wrq->flags & IW_RETRY_LIFETIME) {
1130                 pDevice->wMaxTransmitMSDULifetime = wrq->value;
1131         }
1132
1133
1134         return rc;
1135 }
1136
1137 /*
1138  * Wireless Handler : get retry threshold
1139  */
1140 int iwctl_giwretry(struct net_device *dev,
1141              struct iw_request_info *info,
1142                          struct iw_param *wrq,
1143              char *extra)
1144 {
1145     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1146     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
1147         wrq->disabled = 0;      // Can't be disabled
1148
1149         // Note : by default, display the min retry number
1150         if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1151                 wrq->flags = IW_RETRY_LIFETIME;
1152                 wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
1153         } else if((wrq->flags & IW_RETRY_MAX)) {
1154                 wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1155                 wrq->value = (int)pDevice->byLongRetryLimit;
1156         } else {
1157                 wrq->flags = IW_RETRY_LIMIT;
1158                 wrq->value = (int)pDevice->byShortRetryLimit;
1159                 if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
1160                         wrq->flags |= IW_RETRY_MIN;
1161         }
1162
1163
1164         return 0;
1165 }
1166
1167
1168 /*
1169  * Wireless Handler : set encode mode
1170  */
1171 int iwctl_siwencode(struct net_device *dev,
1172              struct iw_request_info *info,
1173              struct iw_point *wrq,
1174              char *extra)
1175 {
1176     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1177     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1178         DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
1179         int ii,uu, rc = 0;
1180         int index = (wrq->flags & IW_ENCODE_INDEX);
1181
1182
1183     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
1184
1185         // Check the size of the key
1186         if (wrq->length > WLAN_WEP232_KEYLEN) {
1187                 rc = -EINVAL;
1188         return rc;
1189         }
1190
1191         if (dwKeyIndex > WLAN_WEP_NKEYS) {
1192                 rc = -EINVAL;
1193         return rc;
1194     }
1195
1196     if (dwKeyIndex > 0)
1197                 dwKeyIndex--;
1198
1199         // Send the key to the card
1200         if (wrq->length > 0) {
1201
1202         if (wrq->length ==  WLAN_WEP232_KEYLEN) {
1203             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
1204         }
1205         else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
1206             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
1207         }
1208         else if (wrq->length == WLAN_WEP40_KEYLEN) {
1209             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
1210         }
1211         memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
1212         memcpy(pDevice->abyKey, extra, wrq->length);
1213
1214         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
1215         for (ii = 0; ii < wrq->length; ii++) {
1216             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
1217         }
1218
1219         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1220             spin_lock_irq(&pDevice->lock);
1221             KeybSetDefaultKey(  pDevice,
1222                                 &(pDevice->sKey),
1223                                 dwKeyIndex | (1 << 31),
1224                                 wrq->length,
1225                                 NULL,
1226                                 pDevice->abyKey,
1227                                 KEY_CTL_WEP
1228                               );
1229             spin_unlock_irq(&pDevice->lock);
1230         }
1231         pDevice->byKeyIndex = (BYTE)dwKeyIndex;
1232         pDevice->uKeyLength = wrq->length;
1233         pDevice->bTransmitKey = TRUE;
1234         pDevice->bEncryptionEnable = TRUE;
1235         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1236
1237                 // Do we want to just set the transmit key index ?
1238                 if ( index < 4 ) {
1239                     pDevice->byKeyIndex = index;
1240                 } else if (!(wrq->flags & IW_ENCODE_MODE)) {
1241                                 rc = -EINVAL;
1242                                 return rc;
1243             }
1244         }
1245         // Read the flags
1246         if(wrq->flags & IW_ENCODE_DISABLED){
1247
1248         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
1249                 pMgmt->bShareKeyAlgorithm = FALSE;
1250         pDevice->bEncryptionEnable = FALSE;
1251         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1252         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1253             spin_lock_irq(&pDevice->lock);
1254             for (uu = 0; uu < MAX_KEY_TABLE; uu++)
1255                 MACvDisableKeyEntry(pDevice, uu);
1256             spin_unlock_irq(&pDevice->lock);
1257         }
1258         }
1259         if(wrq->flags & IW_ENCODE_RESTRICTED) {
1260         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
1261                 pMgmt->bShareKeyAlgorithm = TRUE;
1262         }
1263         if(wrq->flags & IW_ENCODE_OPEN) {
1264             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
1265                 pMgmt->bShareKeyAlgorithm = FALSE;
1266         }
1267
1268 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1269            memset(pMgmt->abyDesireBSSID, 0xFF,6);
1270 #endif
1271
1272         return rc;
1273 }
1274
1275 int iwctl_giwencode(struct net_device *dev,
1276                         struct iw_request_info *info,
1277                         struct iw_point *wrq,
1278                         char *extra)
1279 {
1280         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1281         PSMgmtObject            pMgmt = &(pDevice->sMgmtObj);
1282         char abyKey[WLAN_WEP232_KEYLEN];
1283
1284         unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
1285         PSKeyItem       pKey = NULL;
1286
1287         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1288
1289         if (index > WLAN_WEP_NKEYS) {
1290                 return  -EINVAL;
1291         }
1292         if(index<1){//get default key
1293                 if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
1294                         index=pDevice->byKeyIndex;
1295                 } else
1296                       index=0;
1297         }else
1298              index--;
1299
1300         memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1301         // Check encryption mode
1302         wrq->flags = IW_ENCODE_NOKEY;
1303         // Is WEP enabled ???
1304         if (pDevice->bEncryptionEnable)
1305                 wrq->flags |=  IW_ENCODE_ENABLED;
1306         else
1307                 wrq->flags |=  IW_ENCODE_DISABLED;
1308
1309         if (pMgmt->bShareKeyAlgorithm)
1310                 wrq->flags |=  IW_ENCODE_RESTRICTED;
1311         else
1312                 wrq->flags |=  IW_ENCODE_OPEN;
1313                 wrq->length=0;
1314
1315         if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
1316                 pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise  key
1317                         if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
1318                            wrq->length = pKey->uKeyLength;
1319                                   memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1320                                   memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1321                            }
1322         }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
1323                         wrq->length = pKey->uKeyLength;
1324                         memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
1325                 memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
1326         }
1327
1328         wrq->flags |= index+1;
1329
1330         return 0;
1331 }
1332
1333
1334 /*
1335  * Wireless Handler : set power mode
1336  */
1337 int iwctl_siwpower(struct net_device *dev,
1338              struct iw_request_info *info,
1339                          struct iw_param *wrq,
1340              char *extra)
1341 {
1342     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1343     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1344     int rc = 0;
1345
1346     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
1347
1348     if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1349                  rc = -EINVAL;
1350                  return rc;
1351         }
1352
1353         if (wrq->disabled) {
1354                 pDevice->ePSMode = WMAC_POWER_CAM;
1355                 PSvDisablePowerSaving(pDevice);
1356                 return rc;
1357         }
1358         if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1359          pDevice->ePSMode = WMAC_POWER_FAST;
1360          PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
1361
1362         } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
1363              pDevice->ePSMode = WMAC_POWER_FAST;
1364              PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval);
1365         }
1366         switch (wrq->flags & IW_POWER_MODE) {
1367         case IW_POWER_UNICAST_R:
1368         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
1369                 rc = -EINVAL;
1370                 break;
1371         case IW_POWER_ALL_R:
1372         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
1373                 rc = -EINVAL;
1374         case IW_POWER_ON:
1375         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
1376                 break;
1377         default:
1378                 rc = -EINVAL;
1379         }
1380
1381         return rc;
1382 }
1383
1384 /*
1385  * Wireless Handler : get power mode
1386  */
1387 int iwctl_giwpower(struct net_device *dev,
1388              struct iw_request_info *info,
1389                          struct iw_param *wrq,
1390              char *extra)
1391 {
1392     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1393     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1394     int mode = pDevice->ePSMode;
1395
1396
1397     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
1398
1399
1400         if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
1401             return 0;
1402
1403         if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1404                 wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1405                 wrq->flags = IW_POWER_TIMEOUT;
1406         } else {
1407                 wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
1408                 wrq->flags = IW_POWER_PERIOD;
1409         }
1410         wrq->flags |= IW_POWER_ALL_R;
1411
1412         return 0;
1413 }
1414
1415
1416 /*
1417  * Wireless Handler : get Sensitivity
1418  */
1419 int iwctl_giwsens(struct net_device *dev,
1420                          struct iw_request_info *info,
1421                          struct iw_param *wrq,
1422                          char *extra)
1423 {
1424     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1425     long ldBm;
1426
1427     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
1428     if (pDevice->bLinkPass == TRUE) {
1429         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
1430             wrq->value = ldBm;
1431         }
1432         else {
1433             wrq->value = 0;
1434     };
1435         wrq->disabled = (wrq->value == 0);
1436         wrq->fixed = 1;
1437
1438
1439         return 0;
1440 }
1441
1442 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1443
1444 int iwctl_siwauth(struct net_device *dev,
1445                           struct iw_request_info *info,
1446                           struct iw_param *wrq,
1447                           char *extra)
1448 {
1449         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1450         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1451         int ret=0;
1452         static int wpa_version=0;  //must be static to save the last value,einsn liu
1453         static int pairwise=0;
1454
1455     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1456         switch (wrq->flags & IW_AUTH_INDEX) {
1457         case IW_AUTH_WPA_VERSION:
1458                 wpa_version = wrq->value;
1459                 if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
1460                        PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
1461                 }
1462                 else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
1463                           PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
1464                 }
1465                 else {
1466                           PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
1467                 }
1468                 break;
1469         case IW_AUTH_CIPHER_PAIRWISE:
1470                 pairwise = wrq->value;
1471                    PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
1472                 if(pairwise == IW_AUTH_CIPHER_CCMP){
1473                         pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1474                 }else if(pairwise == IW_AUTH_CIPHER_TKIP){
1475                         pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1476                 } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
1477                            pairwise == IW_AUTH_CIPHER_WEP104) {
1478                         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1479                 }else if(pairwise == IW_AUTH_CIPHER_NONE){
1480                         //do nothing,einsn liu
1481                 }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1482
1483                 break;
1484         case IW_AUTH_CIPHER_GROUP:
1485                  PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
1486                 if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
1487                         break;
1488                 if(pairwise == IW_AUTH_CIPHER_NONE){
1489                         if(wrq->value == IW_AUTH_CIPHER_CCMP){
1490                                 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1491                         }else {
1492                                 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1493                         }
1494                 }
1495                 break;
1496         case IW_AUTH_KEY_MGMT:
1497                     PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
1498                 if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
1499                         if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1500                                 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1501                         else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
1502                 }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
1503                         if(wrq->value == 0){
1504                                 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
1505                         }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
1506                                 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
1507                         else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
1508                 }
1509
1510                 break;
1511         case IW_AUTH_TKIP_COUNTERMEASURES:
1512                 break;          /* FIXME */
1513         case IW_AUTH_DROP_UNENCRYPTED:
1514                 break;
1515         case IW_AUTH_80211_AUTH_ALG:
1516                  PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
1517                 if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
1518                         pMgmt->bShareKeyAlgorithm=FALSE;
1519                 }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
1520                         pMgmt->bShareKeyAlgorithm=TRUE;
1521                 }
1522                 break;
1523         case IW_AUTH_WPA_ENABLED:
1524                 break;
1525         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1526                 break;
1527         case IW_AUTH_ROAMING_CONTROL:
1528                 ret = -EOPNOTSUPP;
1529                 break;
1530         case IW_AUTH_PRIVACY_INVOKED:
1531                 pDevice->bEncryptionEnable = !!wrq->value;
1532                 if(pDevice->bEncryptionEnable == FALSE){
1533                         wpa_version = 0;
1534                         pairwise = 0;
1535                         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1536                         pMgmt->bShareKeyAlgorithm = FALSE;
1537                         pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
1538                          PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
1539                 }
1540
1541                 break;
1542         default:
1543                 ret = -EOPNOTSUPP;
1544                 break;
1545         }
1546    return ret;
1547 }
1548
1549
1550 int iwctl_giwauth(struct net_device *dev,
1551                           struct iw_request_info *info,
1552                           struct iw_param *wrq,
1553                           char *extra)
1554 {
1555         return -EOPNOTSUPP;
1556 }
1557
1558
1559
1560 int iwctl_siwgenie(struct net_device *dev,
1561                           struct iw_request_info *info,
1562                           struct iw_point *wrq,
1563                           char *extra)
1564 {
1565         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1566         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1567         int ret=0;
1568
1569         if(wrq->length){
1570                 if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
1571                         ret = -EINVAL;
1572                         goto out;
1573                 }
1574                 if(wrq->length > MAX_WPA_IE_LEN){
1575                         ret = -ENOMEM;
1576                         goto out;
1577                 }
1578                 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1579                 if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
1580                         ret = -EFAULT;
1581                         goto out;
1582                 }
1583                 pMgmt->wWPAIELen = wrq->length;
1584         }else {
1585                 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1586                 pMgmt->wWPAIELen = 0;
1587         }
1588
1589         out://not completely ...not necessary in wpa_supplicant 0.5.8
1590         return ret;
1591 }
1592
1593 int iwctl_giwgenie(struct net_device *dev,
1594                           struct iw_request_info *info,
1595                           struct iw_point *wrq,
1596                           char *extra)
1597 {
1598         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1599         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1600         int ret=0;
1601         int space = wrq->length;
1602
1603         wrq->length = 0;
1604         if(pMgmt->wWPAIELen > 0){
1605                 wrq->length = pMgmt->wWPAIELen;
1606                 if(pMgmt->wWPAIELen <= space){
1607                         if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
1608                                 ret = -EFAULT;
1609                         }
1610                 }else
1611                         ret = -E2BIG;
1612         }
1613
1614         return ret;
1615 }
1616
1617
1618 int iwctl_siwencodeext(struct net_device *dev,
1619              struct iw_request_info *info,
1620              struct iw_point *wrq,
1621              char *extra)
1622 {
1623     PSDevice            pDevice = (PSDevice)netdev_priv(dev);
1624     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
1625         struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1626     struct viawget_wpa_param *param=NULL;
1627 //original member
1628     wpa_alg alg_name;
1629     u8  addr[6];
1630     int key_idx, set_tx=0;
1631     u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
1632     u8 key[64];
1633     size_t seq_len=0,key_len=0;
1634     u8 *buf;
1635     size_t blen;
1636     u8 key_array[64];
1637     int ret=0;
1638
1639 PRINT_K("SIOCSIWENCODEEXT...... \n");
1640
1641 blen = sizeof(*param);
1642 buf = kmalloc((int)blen, (int)GFP_KERNEL);
1643 if (buf == NULL)
1644     return -ENOMEM;
1645 memset(buf, 0, blen);
1646 param = (struct viawget_wpa_param *) buf;
1647
1648 //recover alg_name
1649 switch (ext->alg) {
1650     case IW_ENCODE_ALG_NONE:
1651                   alg_name = WPA_ALG_NONE;
1652                 break;
1653     case IW_ENCODE_ALG_WEP:
1654                   alg_name = WPA_ALG_WEP;
1655                 break;
1656     case IW_ENCODE_ALG_TKIP:
1657                   alg_name = WPA_ALG_TKIP;
1658                 break;
1659     case IW_ENCODE_ALG_CCMP:
1660                   alg_name = WPA_ALG_CCMP;
1661                 break;
1662     default:
1663                 PRINT_K("Unknown alg = %d\n",ext->alg);
1664                 ret= -ENOMEM;
1665                 goto error;
1666                 }
1667 //recover addr
1668  memcpy(addr, ext->addr.sa_data, ETH_ALEN);
1669 //recover key_idx
1670   key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
1671 //recover set_tx
1672 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1673    set_tx = 1;
1674 //recover seq,seq_len
1675         if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1676    seq_len=IW_ENCODE_SEQ_MAX_SIZE;
1677    memcpy(seq, ext->rx_seq, seq_len);
1678                 }
1679 //recover key,key_len
1680 if(ext->key_len) {
1681   key_len=ext->key_len;
1682   memcpy(key, &ext->key[0], key_len);
1683         }
1684
1685 memset(key_array, 0, 64);
1686 if ( key_len > 0) {
1687      memcpy(key_array, key, key_len);
1688     if (key_len == 32) {
1689           // notice ! the oder
1690           memcpy(&key_array[16], &key[24], 8);
1691           memcpy(&key_array[24], &key[16], 8);
1692         }
1693         }
1694
1695 /**************Translate iw_encode_ext to viawget_wpa_param****************/
1696 memcpy(param->addr, addr, ETH_ALEN);
1697 param->u.wpa_key.alg_name = (int)alg_name;
1698 param->u.wpa_key.set_tx = set_tx;
1699 param->u.wpa_key.key_index = key_idx;
1700 param->u.wpa_key.key_len = key_len;
1701 param->u.wpa_key.key = (u8 *)key_array;
1702 param->u.wpa_key.seq = (u8 *)seq;
1703 param->u.wpa_key.seq_len = seq_len;
1704
1705 //****set if current action is Network Manager count??
1706 //****this method is so foolish,but there is no other way???
1707 if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
1708    if(param->u.wpa_key.key_index ==0) {
1709      pDevice->bwextstep0 = TRUE;
1710     }
1711    if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
1712      pDevice->bwextstep0 = FALSE;
1713      pDevice->bwextstep1 = TRUE;
1714     }
1715    if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
1716      pDevice->bwextstep1 = FALSE;
1717      pDevice->bwextstep2 = TRUE;
1718         }
1719    if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
1720      pDevice->bwextstep2 = FALSE;
1721      pDevice->bwextstep3 = TRUE;
1722         }
1723                  }
1724 if(pDevice->bwextstep3 == TRUE) {
1725     PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
1726      pDevice->bwextstep0 = FALSE;
1727      pDevice->bwextstep1 = FALSE;
1728      pDevice->bwextstep2 = FALSE;
1729      pDevice->bwextstep3 = FALSE;
1730      pDevice->bWPASuppWextEnabled = TRUE;
1731      memset(pMgmt->abyDesireBSSID, 0xFF,6);
1732      KeyvInitTable(pDevice,&pDevice->sKey);
1733                  }
1734 //******
1735
1736                 spin_lock_irq(&pDevice->lock);
1737  ret = wpa_set_keys(pDevice, param, TRUE);
1738                 spin_unlock_irq(&pDevice->lock);
1739
1740 error:
1741 kfree(param);
1742         return ret;
1743 }
1744
1745
1746
1747 int iwctl_giwencodeext(struct net_device *dev,
1748              struct iw_request_info *info,
1749              struct iw_point *wrq,
1750              char *extra)
1751 {
1752                 return -EOPNOTSUPP;
1753 }
1754
1755 int iwctl_siwmlme(struct net_device *dev,
1756                                 struct iw_request_info * info,
1757                                 struct iw_point *wrq,
1758                                 char *extra)
1759 {
1760         PSDevice                        pDevice = (PSDevice)netdev_priv(dev);
1761         PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
1762         struct iw_mlme *mlme = (struct iw_mlme *)extra;
1763         int ret = 0;
1764
1765         if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
1766                 ret = -EINVAL;
1767                 return ret;
1768         }
1769         switch(mlme->cmd){
1770         case IW_MLME_DEAUTH:
1771         case IW_MLME_DISASSOC:
1772                 if(pDevice->bLinkPass == TRUE){
1773                   PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
1774                   bScheduleCommand((void *) pDevice,
1775                                    WLAN_CMD_DISASSOCIATE,
1776                                    NULL);
1777                 }
1778                 break;
1779         default:
1780                 ret = -EOPNOTSUPP;
1781         }
1782
1783         return ret;
1784
1785 }
1786
1787 #endif
1788
1789 static const iw_handler         iwctl_handler[] =
1790 {
1791         (iw_handler) NULL,      /* SIOCSIWCOMMIT */
1792         (iw_handler) NULL,      // SIOCGIWNAME
1793         (iw_handler) NULL,                              // SIOCSIWNWID
1794         (iw_handler) NULL,                              // SIOCGIWNWID
1795         (iw_handler) NULL,              // SIOCSIWFREQ
1796         (iw_handler) NULL,              // SIOCGIWFREQ
1797         (iw_handler) NULL,              // SIOCSIWMODE
1798         (iw_handler) NULL,              // SIOCGIWMODE
1799         (iw_handler) NULL,                      // SIOCSIWSENS
1800         (iw_handler) NULL,                      // SIOCGIWSENS
1801         (iw_handler) NULL,                      // SIOCSIWRANGE
1802         (iw_handler) iwctl_giwrange,            // SIOCGIWRANGE
1803         (iw_handler) NULL,                          // SIOCSIWPRIV
1804         (iw_handler) NULL,                      // SIOCGIWPRIV
1805         (iw_handler) NULL,                      // SIOCSIWSTATS
1806         (iw_handler) NULL,                  // SIOCGIWSTATS
1807     (iw_handler) NULL,                  // SIOCSIWSPY
1808         (iw_handler) NULL,                          // SIOCGIWSPY
1809         (iw_handler) NULL,                                  // -- hole --
1810         (iw_handler) NULL,                                  // -- hole --
1811         (iw_handler) NULL,                  // SIOCSIWAP
1812         (iw_handler) NULL,                  // SIOCGIWAP
1813         (iw_handler) NULL,                                  // -- hole -- 0x16
1814         (iw_handler) NULL,       // SIOCGIWAPLIST
1815         (iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
1816         (iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
1817         (iw_handler) NULL,              // SIOCSIWESSID
1818         (iw_handler) NULL,              // SIOCGIWESSID
1819         (iw_handler) NULL,              // SIOCSIWNICKN
1820         (iw_handler) NULL,              // SIOCGIWNICKN
1821         (iw_handler) NULL,              // -- hole --
1822         (iw_handler) NULL,              // -- hole --
1823         (iw_handler) NULL,              // SIOCSIWRATE 0x20
1824         (iw_handler) NULL,              // SIOCGIWRATE
1825         (iw_handler) NULL,              // SIOCSIWRTS
1826         (iw_handler) NULL,              // SIOCGIWRTS
1827         (iw_handler) NULL,              // SIOCSIWFRAG
1828         (iw_handler) NULL,              // SIOCGIWFRAG
1829         (iw_handler) NULL,              // SIOCSIWTXPOW
1830         (iw_handler) NULL,              // SIOCGIWTXPOW
1831         (iw_handler) NULL,              // SIOCSIWRETRY
1832         (iw_handler) NULL,              // SIOCGIWRETRY
1833         (iw_handler) NULL,              // SIOCSIWENCODE
1834         (iw_handler) NULL,              // SIOCGIWENCODE
1835         (iw_handler) NULL,              // SIOCSIWPOWER
1836         (iw_handler) NULL,              // SIOCGIWPOWER
1837         (iw_handler) NULL,                      // -- hole --
1838         (iw_handler) NULL,                      // -- hole --
1839         (iw_handler) NULL,    // SIOCSIWGENIE
1840         (iw_handler) NULL,    // SIOCGIWGENIE
1841         (iw_handler) NULL,              // SIOCSIWAUTH
1842         (iw_handler) NULL,              // SIOCGIWAUTH
1843         (iw_handler) NULL,              // SIOCSIWENCODEEXT
1844         (iw_handler) NULL,              // SIOCGIWENCODEEXT
1845         (iw_handler) NULL,                              // SIOCSIWPMKSA
1846         (iw_handler) NULL,                              // -- hole --
1847 };
1848
1849
1850 static const iw_handler         iwctl_private_handler[] =
1851 {
1852         NULL,                           // SIOCIWFIRSTPRIV
1853 };
1854
1855
1856 struct iw_priv_args iwctl_private_args[] = {
1857 { IOCTL_CMD_SET,
1858   IW_PRIV_TYPE_CHAR | 1024, 0,
1859   "set"},
1860 };
1861
1862
1863
1864 const struct iw_handler_def     iwctl_handler_def =
1865 {
1866         .get_wireless_stats = &iwctl_get_wireless_stats,
1867         .num_standard   = sizeof(iwctl_handler)/sizeof(iw_handler),
1868         .num_private    = 0,
1869         .num_private_args = 0,
1870         .standard       = (iw_handler *) iwctl_handler,
1871         .private        = NULL,
1872         .private_args   = NULL,
1873 };