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