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