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