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