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