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