xfs: remote attribute lookups require the value length
[GitHub/mt8127/android_kernel_alcatel_ttab.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 if (wrq->disabled) {
1349 pDevice->ePSMode = WMAC_POWER_CAM;
1350 PSvDisablePowerSaving(pDevice);
1351 return rc;
1352 }
1353 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1354 pDevice->ePSMode = WMAC_POWER_FAST;
1355 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
1356
1357 } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
1358 pDevice->ePSMode = WMAC_POWER_FAST;
1359 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
1360 }
1361 switch (wrq->flags & IW_POWER_MODE) {
1362 case IW_POWER_UNICAST_R:
1363 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
1364 rc = -EINVAL;
1365 break;
1366 case IW_POWER_ALL_R:
1367 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
1368 rc = -EINVAL;
1369 case IW_POWER_ON:
1370 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
1371 break;
1372 default:
1373 rc = -EINVAL;
1374 }
1375
1376 return rc;
1377 }
1378
1379 /*
1380 * Wireless Handler: get power mode
1381 */
1382 int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
1383 union iwreq_data *wrqu, char *extra)
1384 {
1385 struct vnt_private *pDevice = netdev_priv(dev);
1386 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1387 struct iw_param *wrq = &wrqu->power;
1388 int mode = pDevice->ePSMode;
1389
1390 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
1391
1392 if (pMgmt == NULL)
1393 return -EFAULT;
1394
1395 if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
1396 return 0;
1397
1398 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1399 wrq->value = (int)((pMgmt->wListenInterval *
1400 pMgmt->wCurrBeaconPeriod) / 100);
1401 wrq->flags = IW_POWER_TIMEOUT;
1402 } else {
1403 wrq->value = (int)((pMgmt->wListenInterval *
1404 pMgmt->wCurrBeaconPeriod) / 100);
1405 wrq->flags = IW_POWER_PERIOD;
1406 }
1407
1408 wrq->flags |= IW_POWER_ALL_R;
1409 return 0;
1410 }
1411
1412 /*
1413 * Wireless Handler: get Sensitivity
1414 */
1415 int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
1416 union iwreq_data *wrqu, char *extra)
1417 {
1418 struct vnt_private *pDevice = netdev_priv(dev);
1419 struct iw_param *wrq = &wrqu->sens;
1420 long ldBm;
1421
1422 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
1423 if (pDevice->bLinkPass == true) {
1424 RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
1425 wrq->value = ldBm;
1426 } else {
1427 wrq->value = 0;
1428 }
1429 wrq->disabled = (wrq->value == 0);
1430 wrq->fixed = 1;
1431 return 0;
1432 }
1433
1434 int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
1435 union iwreq_data *wrqu, char *extra)
1436 {
1437 struct vnt_private *pDevice = netdev_priv(dev);
1438 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1439 struct iw_param *wrq = &wrqu->param;
1440 int ret = 0;
1441 static int wpa_version = 0; // must be static to save the last value, einsn liu
1442 static int pairwise = 0;
1443
1444 if (pMgmt == NULL)
1445 return -EFAULT;
1446
1447 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
1448 switch (wrq->flags & IW_AUTH_INDEX) {
1449 case IW_AUTH_WPA_VERSION:
1450 wpa_version = wrq->value;
1451 if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
1452 PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
1453 } else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) {
1454 PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
1455 } else {
1456 PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
1457 }
1458 break;
1459 case IW_AUTH_CIPHER_PAIRWISE:
1460 pairwise = wrq->value;
1461 PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
1462 if (pairwise == IW_AUTH_CIPHER_CCMP){
1463 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1464 } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
1465 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1466 } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
1467 pairwise == IW_AUTH_CIPHER_WEP104) {
1468 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1469 } else if (pairwise == IW_AUTH_CIPHER_NONE) {
1470 // do nothing, einsn liu
1471 } else {
1472 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1473 }
1474 break;
1475 case IW_AUTH_CIPHER_GROUP:
1476 PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value);
1477 if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
1478 break;
1479 if (pairwise == IW_AUTH_CIPHER_NONE) {
1480 if (wrq->value == IW_AUTH_CIPHER_CCMP)
1481 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1482 else
1483 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1484 }
1485 break;
1486 case IW_AUTH_KEY_MGMT:
1487 PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version,wrq->value);
1488 if (wpa_version == IW_AUTH_WPA_VERSION_WPA2){
1489 if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
1490 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1491 else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
1492 } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
1493 if (wrq->value == 0){
1494 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
1495 } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
1496 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
1497 } else {
1498 pMgmt->eAuthenMode = WMAC_AUTH_WPA;
1499 }
1500 break;
1501 case IW_AUTH_TKIP_COUNTERMEASURES:
1502 break; /* FIXME */
1503 case IW_AUTH_DROP_UNENCRYPTED:
1504 break;
1505 case IW_AUTH_80211_AUTH_ALG:
1506 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value);
1507 if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM)
1508 pMgmt->bShareKeyAlgorithm = false;
1509 else if (wrq->value == IW_AUTH_ALG_SHARED_KEY)
1510 pMgmt->bShareKeyAlgorithm = true;
1511 break;
1512 case IW_AUTH_WPA_ENABLED:
1513 break;
1514 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1515 break;
1516 case IW_AUTH_ROAMING_CONTROL:
1517 ret = -EOPNOTSUPP;
1518 break;
1519 case IW_AUTH_PRIVACY_INVOKED:
1520 pDevice->bEncryptionEnable = !!wrq->value;
1521 if (pDevice->bEncryptionEnable == false) {
1522 wpa_version = 0;
1523 pairwise = 0;
1524 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1525 pMgmt->bShareKeyAlgorithm = false;
1526 pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
1527 PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
1528 }
1529 break;
1530 default:
1531 PRINT_K("iwctl_siwauth: not supported %x\n", wrq->flags);
1532 ret = -EOPNOTSUPP;
1533 break;
1534 }
1535 return ret;
1536 }
1537
1538 int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
1539 union iwreq_data *wrqu, char *extra)
1540 {
1541 return -EOPNOTSUPP;
1542 }
1543
1544 int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
1545 union iwreq_data *wrqu, char *extra)
1546 {
1547 struct vnt_private *pDevice = netdev_priv(dev);
1548 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1549 struct iw_point *wrq = &wrqu->data;
1550 int ret = 0;
1551
1552 if (pMgmt == NULL)
1553 return -EFAULT;
1554
1555 if (wrq->length){
1556 if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
1557 ret = -EINVAL;
1558 goto out;
1559 }
1560 if (wrq->length > MAX_WPA_IE_LEN){
1561 ret = -ENOMEM;
1562 goto out;
1563 }
1564 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1565 if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
1566 ret = -EFAULT;
1567 goto out;
1568 }
1569 pMgmt->wWPAIELen = wrq->length;
1570 } else {
1571 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1572 pMgmt->wWPAIELen = 0;
1573 }
1574
1575 out: // not completely ...not necessary in wpa_supplicant 0.5.8
1576 return ret;
1577 }
1578
1579 int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
1580 union iwreq_data *wrqu, char *extra)
1581 {
1582 struct vnt_private *pDevice = netdev_priv(dev);
1583 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1584 struct iw_point *wrq = &wrqu->data;
1585 int ret = 0;
1586 int space = wrq->length;
1587
1588 if (pMgmt == NULL)
1589 return -EFAULT;
1590
1591 wrq->length = 0;
1592 if (pMgmt->wWPAIELen > 0) {
1593 wrq->length = pMgmt->wWPAIELen;
1594 if (pMgmt->wWPAIELen <= space) {
1595 if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)) {
1596 ret = -EFAULT;
1597 }
1598 } else {
1599 ret = -E2BIG;
1600 }
1601 }
1602 return ret;
1603 }
1604
1605 int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
1606 union iwreq_data *wrqu, char *extra)
1607 {
1608 struct vnt_private *pDevice = netdev_priv(dev);
1609 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1610 struct iw_point *wrq = &wrqu->encoding;
1611 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1612 struct viawget_wpa_param *param=NULL;
1613 // original member
1614 wpa_alg alg_name;
1615 u8 addr[6];
1616 int key_idx;
1617 int set_tx = 0;
1618 u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
1619 u8 key[64];
1620 size_t seq_len = 0;
1621 size_t key_len = 0;
1622 u8 *buf;
1623 u8 key_array[64];
1624 int ret = 0;
1625
1626 PRINT_K("SIOCSIWENCODEEXT......\n");
1627
1628 if (pMgmt == NULL)
1629 return -EFAULT;
1630
1631 buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
1632 if (buf == NULL)
1633 return -ENOMEM;
1634
1635 param = (struct viawget_wpa_param *)buf;
1636
1637 // recover alg_name
1638 switch (ext->alg) {
1639 case IW_ENCODE_ALG_NONE:
1640 alg_name = WPA_ALG_NONE;
1641 break;
1642 case IW_ENCODE_ALG_WEP:
1643 alg_name = WPA_ALG_WEP;
1644 break;
1645 case IW_ENCODE_ALG_TKIP:
1646 alg_name = WPA_ALG_TKIP;
1647 break;
1648 case IW_ENCODE_ALG_CCMP:
1649 alg_name = WPA_ALG_CCMP;
1650 break;
1651 default:
1652 PRINT_K("Unknown alg = %d\n",ext->alg);
1653 ret= -ENOMEM;
1654 goto error;
1655 }
1656 // recover addr
1657 memcpy(addr, ext->addr.sa_data, ETH_ALEN);
1658 // recover key_idx
1659 key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
1660 // recover set_tx
1661 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1662 set_tx = 1;
1663 // recover seq,seq_len
1664 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1665 seq_len=IW_ENCODE_SEQ_MAX_SIZE;
1666 memcpy(seq, ext->rx_seq, seq_len);
1667 }
1668 // recover key,key_len
1669 if (ext->key_len) {
1670 key_len = ext->key_len;
1671 memcpy(key, &ext->key[0], key_len);
1672 }
1673 memset(key_array, 0, 64);
1674 if (key_len > 0) {
1675 memcpy(key_array, key, key_len);
1676 if (key_len == 32) {
1677 // notice ! the oder
1678 memcpy(&key_array[16], &key[24], 8);
1679 memcpy(&key_array[24], &key[16], 8);
1680 }
1681 }
1682
1683 /**************Translate iw_encode_ext to viawget_wpa_param****************/
1684 memcpy(param->addr, addr, ETH_ALEN);
1685 param->u.wpa_key.alg_name = (int)alg_name;
1686 param->u.wpa_key.set_tx = set_tx;
1687 param->u.wpa_key.key_index = key_idx;
1688 param->u.wpa_key.key_len = key_len;
1689 param->u.wpa_key.key = (u8 *)key_array;
1690 param->u.wpa_key.seq = (u8 *)seq;
1691 param->u.wpa_key.seq_len = seq_len;
1692
1693 /****set if current action is Network Manager count?? */
1694 /****this method is so foolish,but there is no other way??? */
1695 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
1696 if (param->u.wpa_key.key_index ==0) {
1697 pDevice->bwextstep0 = true;
1698 }
1699 if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
1700 pDevice->bwextstep0 = false;
1701 pDevice->bwextstep1 = true;
1702 }
1703 if ((pDevice->bwextstep1 == true) && (param->u.wpa_key.key_index == 2)) {
1704 pDevice->bwextstep1 = false;
1705 pDevice->bwextstep2 = true;
1706 }
1707 if ((pDevice->bwextstep2 == true) && (param->u.wpa_key.key_index == 3)) {
1708 pDevice->bwextstep2 = false;
1709 pDevice->bwextstep3 = true;
1710 }
1711 }
1712 if (pDevice->bwextstep3 == true) {
1713 PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
1714 pDevice->bwextstep0 = false;
1715 pDevice->bwextstep1 = false;
1716 pDevice->bwextstep2 = false;
1717 pDevice->bwextstep3 = false;
1718 pDevice->bWPASuppWextEnabled = true;
1719 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
1720 KeyvInitTable(pDevice, &pDevice->sKey);
1721 }
1722 /*******/
1723 spin_lock_irq(&pDevice->lock);
1724 ret = wpa_set_keys(pDevice, param);
1725 spin_unlock_irq(&pDevice->lock);
1726
1727 error:
1728 kfree(buf);
1729 return ret;
1730 }
1731
1732 int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
1733 union iwreq_data *wrqu, char *extra)
1734 {
1735 return -EOPNOTSUPP;
1736 }
1737
1738 int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
1739 union iwreq_data *wrqu, char *extra)
1740 {
1741 struct vnt_private *pDevice = netdev_priv(dev);
1742 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1743 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1744 int ret = 0;
1745
1746 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
1747
1748 if (pMgmt == NULL)
1749 return -EFAULT;
1750
1751 if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
1752 ret = -EINVAL;
1753 return ret;
1754 }
1755 switch (mlme->cmd){
1756 case IW_MLME_DEAUTH:
1757 case IW_MLME_DISASSOC:
1758 if (pDevice->bLinkPass == true) {
1759 PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
1760 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE,
1761 NULL);
1762 }
1763 break;
1764 default:
1765 ret = -EOPNOTSUPP;
1766 }
1767 return ret;
1768 }
1769
1770 static int iwctl_config_commit(struct net_device *dev,
1771 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1772 {
1773 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SIOCSIWCOMMIT\n");
1774
1775 return 0;
1776 }
1777
1778 static const iw_handler iwctl_handler[] = {
1779 IW_HANDLER(SIOCSIWCOMMIT, iwctl_config_commit),
1780 IW_HANDLER(SIOCGIWNAME, iwctl_giwname),
1781 IW_HANDLER(SIOCSIWFREQ, iwctl_siwfreq),
1782 IW_HANDLER(SIOCGIWFREQ, iwctl_giwfreq),
1783 IW_HANDLER(SIOCSIWMODE, iwctl_siwmode),
1784 IW_HANDLER(SIOCGIWMODE, iwctl_giwmode),
1785 IW_HANDLER(SIOCGIWSENS, iwctl_giwsens),
1786 IW_HANDLER(SIOCGIWRANGE, iwctl_giwrange),
1787 IW_HANDLER(SIOCSIWAP, iwctl_siwap),
1788 IW_HANDLER(SIOCGIWAP, iwctl_giwap),
1789 IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
1790 IW_HANDLER(SIOCGIWAPLIST, iwctl_giwaplist),
1791 IW_HANDLER(SIOCSIWSCAN, iwctl_siwscan),
1792 IW_HANDLER(SIOCGIWSCAN, iwctl_giwscan),
1793 IW_HANDLER(SIOCSIWESSID, iwctl_siwessid),
1794 IW_HANDLER(SIOCGIWESSID, iwctl_giwessid),
1795 IW_HANDLER(SIOCSIWRATE, iwctl_siwrate),
1796 IW_HANDLER(SIOCGIWRATE, iwctl_giwrate),
1797 IW_HANDLER(SIOCSIWRTS, iwctl_siwrts),
1798 IW_HANDLER(SIOCGIWRTS, iwctl_giwrts),
1799 IW_HANDLER(SIOCSIWFRAG, iwctl_siwfrag),
1800 IW_HANDLER(SIOCGIWFRAG, iwctl_giwfrag),
1801 IW_HANDLER(SIOCSIWRETRY, iwctl_siwretry),
1802 IW_HANDLER(SIOCGIWRETRY, iwctl_giwretry),
1803 IW_HANDLER(SIOCSIWENCODE, iwctl_siwencode),
1804 IW_HANDLER(SIOCGIWENCODE, iwctl_giwencode),
1805 IW_HANDLER(SIOCSIWPOWER, iwctl_siwpower),
1806 IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
1807 IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
1808 IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
1809 IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
1810 IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
1811 IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
1812 IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
1813 IW_HANDLER(SIOCGIWENCODEEXT, iwctl_giwencodeext)
1814 };
1815
1816 static const iw_handler iwctl_private_handler[] = {
1817 NULL, // SIOCIWFIRSTPRIV
1818 };
1819
1820 const struct iw_handler_def iwctl_handler_def = {
1821 .get_wireless_stats = &iwctl_get_wireless_stats,
1822 .num_standard = ARRAY_SIZE(iwctl_handler),
1823 .num_private = 0,
1824 .num_private_args = 0,
1825 .standard = iwctl_handler,
1826 .private = NULL,
1827 .private_args = NULL,
1828 };