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