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