PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / staging / vt6656 / iwctl.c
blob3a68dfa23d84a684fe039e63712fffdea6b8e51a
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
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.
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.
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.
19 * File: iwctl.c
21 * Purpose: wireless ext & ioctl functions
23 * Author: Lyndon Chen
25 * Date: July 5, 2006
27 * Functions:
29 * Revision History:
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"
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
53 static int msglevel = MSG_LEVEL_INFO;
55 struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
57 struct vnt_private *pDevice = netdev_priv(dev);
58 long ldBm;
60 pDevice->wstats.status = pDevice->eOPMode;
61 RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
62 pDevice->wstats.qual.level = ldBm;
63 pDevice->wstats.qual.noise = 0;
64 pDevice->wstats.qual.updated = 1;
65 pDevice->wstats.discard.nwid = 0;
66 pDevice->wstats.discard.code = 0;
67 pDevice->wstats.discard.fragment = 0;
68 pDevice->wstats.discard.misc = 0;
69 pDevice->wstats.miss.beacon = 0;
70 return &pDevice->wstats;
74 * Wireless Handler: get protocol name
76 int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
77 union iwreq_data *wrqu, char *extra)
79 strcpy(wrqu->name, "802.11-a/b/g");
80 return 0;
84 * Wireless Handler: set scan
86 int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
87 union iwreq_data *wrqu, char *extra)
89 struct vnt_private *pDevice = netdev_priv(dev);
90 struct iw_point *wrq = &wrqu->data;
91 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
92 struct iw_scan_req *req = (struct iw_scan_req *)extra;
93 u8 abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
94 PWLAN_IE_SSID pItemSSID = NULL;
96 if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
97 return -EINVAL;
99 PRINT_K(" SIOCSIWSCAN\n");
101 if (pMgmt == NULL)
102 return -EFAULT;
104 if (pMgmt->eScanState == WMAC_IS_SCANNING) {
105 // In scanning..
106 PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
107 return -EAGAIN;
110 if (pDevice->byReAssocCount > 0) { // reject scan when re-associating!
111 // send scan event to wpa_Supplicant
112 union iwreq_data wrqu;
113 PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
114 memset(&wrqu, 0, sizeof(wrqu));
115 wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
116 return 0;
119 spin_lock_irq(&pDevice->lock);
121 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
123 // mike add: active scan OR passive scan OR desire_ssid scan
124 if (wrq->length == sizeof(struct iw_scan_req)) {
125 if (wrq->flags & IW_SCAN_THIS_ESSID) { // desire_ssid scan
126 memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
127 pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
128 pItemSSID->byElementID = WLAN_EID_SSID;
129 memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
130 if (pItemSSID->abySSID[req->essid_len] == '\0') {
131 if (req->essid_len > 0)
132 pItemSSID->len = req->essid_len;
133 } else {
134 pItemSSID->len = req->essid_len;
136 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
137 PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID,
138 ((PWLAN_IE_SSID)abyScanSSID)->len);
139 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
140 spin_unlock_irq(&pDevice->lock);
142 return 0;
143 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { // passive scan
144 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
146 } else { // active scan
147 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
150 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
151 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
152 spin_unlock_irq(&pDevice->lock);
154 return 0;
158 * Wireless Handler : get scan results
160 int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
161 union iwreq_data *wrqu, char *extra)
163 struct iw_point *wrq = &wrqu->data;
164 int ii;
165 int jj;
166 int kk;
167 struct vnt_private *pDevice = netdev_priv(dev);
168 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
169 PKnownBSS pBSS;
170 PWLAN_IE_SSID pItemSSID;
171 PWLAN_IE_SUPP_RATES pSuppRates;
172 PWLAN_IE_SUPP_RATES pExtSuppRates;
173 char *current_ev = extra;
174 char *end_buf = extra + IW_SCAN_MAX_DATA;
175 char *current_val = NULL;
176 struct iw_event iwe;
177 long ldBm;
179 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
181 if (pMgmt == NULL)
182 return -EFAULT;
184 if (pMgmt->eScanState == WMAC_IS_SCANNING) {
185 // In scanning..
186 return -EAGAIN;
188 pBSS = &(pMgmt->sBSSList[0]);
189 for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) {
190 if (current_ev >= end_buf)
191 break;
192 pBSS = &(pMgmt->sBSSList[jj]);
193 if (pBSS->bActive) {
194 // ADD mac address
195 memset(&iwe, 0, sizeof(iwe));
196 iwe.cmd = SIOCGIWAP;
197 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
198 memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
199 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
200 // ADD ssid
201 memset(&iwe, 0, sizeof(iwe));
202 iwe.cmd = SIOCGIWESSID;
203 pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
204 iwe.u.data.length = pItemSSID->len;
205 iwe.u.data.flags = 1;
206 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID);
207 // ADD mode
208 memset(&iwe, 0, sizeof(iwe));
209 iwe.cmd = SIOCGIWMODE;
210 if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo))
211 iwe.u.mode = IW_MODE_INFRA;
212 else
213 iwe.u.mode = IW_MODE_ADHOC;
214 iwe.len = IW_EV_UINT_LEN;
215 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
216 // ADD frequency
217 pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
218 pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
219 memset(&iwe, 0, sizeof(iwe));
220 iwe.cmd = SIOCGIWFREQ;
221 iwe.u.freq.m = pBSS->uChannel;
222 iwe.u.freq.e = 0;
223 iwe.u.freq.i = 0;
224 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
226 int f = (int)pBSS->uChannel - 1;
227 if (f < 0)
228 f = 0;
229 iwe.u.freq.m = frequency_list[f] * 100000;
230 iwe.u.freq.e = 1;
232 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
233 // ADD quality
234 memset(&iwe, 0, sizeof(iwe));
235 iwe.cmd = IWEVQUAL;
236 RFvRSSITodBm(pDevice, (u8)(pBSS->uRSSI), &ldBm);
237 iwe.u.qual.level = ldBm;
238 iwe.u.qual.noise = 0;
240 if (-ldBm < 50)
241 iwe.u.qual.qual = 100;
242 else if (-ldBm > 90)
243 iwe.u.qual.qual = 0;
244 else
245 iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40;
246 iwe.u.qual.updated = 7;
248 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
249 // ADD encryption
250 memset(&iwe, 0, sizeof(iwe));
251 iwe.cmd = SIOCGIWENCODE;
252 iwe.u.data.length = 0;
253 if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo))
254 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
255 else
256 iwe.u.data.flags = IW_ENCODE_DISABLED;
257 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID);
259 memset(&iwe, 0, sizeof(iwe));
260 iwe.cmd = SIOCGIWRATE;
261 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
262 current_val = current_ev + IW_EV_LCP_LEN;
264 for (kk = 0; kk < 12; kk++) {
265 if (pSuppRates->abyRates[kk] == 0)
266 break;
267 // Bit rate given in 500 kb/s units (+ 0x80)
268 iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
269 current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
271 for (kk = 0; kk < 8; kk++) {
272 if (pExtSuppRates->abyRates[kk] == 0)
273 break;
274 // Bit rate given in 500 kb/s units (+ 0x80)
275 iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
276 current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
279 if ((current_val - current_ev) > IW_EV_LCP_LEN)
280 current_ev = current_val;
282 if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
283 memset(&iwe, 0, sizeof(iwe));
284 iwe.cmd = IWEVGENIE;
285 iwe.u.data.length = pBSS->wWPALen;
286 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE);
289 if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
290 memset(&iwe, 0, sizeof(iwe));
291 iwe.cmd = IWEVGENIE;
292 iwe.u.data.length = pBSS->wRSNLen;
293 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE);
296 } // for
297 wrq->length = current_ev - extra;
298 return 0;
302 * Wireless Handler: set frequence or channel
304 int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
305 union iwreq_data *wrqu, char *extra)
307 struct vnt_private *pDevice = netdev_priv(dev);
308 struct iw_freq *wrq = &wrqu->freq;
309 int rc = 0;
311 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n");
313 // If setting by frequency, convert to a channel
314 if ((wrq->e == 1) && (wrq->m >= (int)2.412e8) &&
315 (wrq->m <= (int)2.487e8)) {
316 int f = wrq->m / 100000;
317 int c = 0;
318 while ((c < 14) && (f != frequency_list[c]))
319 c++;
320 wrq->e = 0;
321 wrq->m = c + 1;
323 // Setting by channel number
324 if ((wrq->m > 14) || (wrq->e > 0)) {
325 rc = -EOPNOTSUPP;
326 } else {
327 int channel = wrq->m;
328 if ((channel < 1) || (channel > 14)) {
329 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
330 rc = -EINVAL;
331 } else {
332 // Yes ! We can set it !!!
333 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
334 pDevice->uChannel = channel;
337 return rc;
341 * Wireless Handler: get frequence or channel
343 int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
344 union iwreq_data *wrqu, char *extra)
346 struct vnt_private *pDevice = netdev_priv(dev);
347 struct iw_freq *wrq = &wrqu->freq;
348 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
350 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n");
352 if (pMgmt == NULL)
353 return -EFAULT;
355 #ifdef WEXT_USECHANNELS
356 wrq->m = (int)pMgmt->uCurrChannel;
357 wrq->e = 0;
358 #else
360 int f = (int)pMgmt->uCurrChannel - 1;
361 if (f < 0)
362 f = 0;
363 wrq->m = frequency_list[f] * 100000;
364 wrq->e = 1;
366 #endif
367 return 0;
371 * Wireless Handler: set operation mode
373 int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
374 union iwreq_data *wrqu, char *extra)
376 struct vnt_private *pDevice = netdev_priv(dev);
377 __u32 *wmode = &wrqu->mode;
378 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
379 int rc = 0;
381 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE\n");
383 if (pMgmt == NULL)
384 return -EFAULT;
386 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
387 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
388 "Can't set operation mode, hostapd is running\n");
389 return rc;
392 switch (*wmode) {
393 case IW_MODE_ADHOC:
394 if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
395 pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
396 if (pDevice->flags & DEVICE_FLAGS_OPENED)
397 pDevice->bCommit = true;
399 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc\n");
400 break;
401 case IW_MODE_AUTO:
402 case IW_MODE_INFRA:
403 if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
404 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
405 if (pDevice->flags & DEVICE_FLAGS_OPENED)
406 pDevice->bCommit = true;
408 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure\n");
409 break;
410 case IW_MODE_MASTER:
412 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
413 rc = -EOPNOTSUPP;
414 break;
416 if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
417 pMgmt->eConfigMode = WMAC_CONFIG_AP;
418 if (pDevice->flags & DEVICE_FLAGS_OPENED)
419 pDevice->bCommit = true;
421 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point\n");
422 break;
424 case IW_MODE_REPEAT:
425 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
426 rc = -EOPNOTSUPP;
427 break;
428 default:
429 rc = -EINVAL;
432 if (pDevice->bCommit) {
433 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
434 netif_stop_queue(pDevice->dev);
435 spin_lock_irq(&pDevice->lock);
436 bScheduleCommand((void *) pDevice,
437 WLAN_CMD_RUN_AP, NULL);
438 spin_unlock_irq(&pDevice->lock);
439 } else {
440 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
441 "Commit the settings\n");
443 spin_lock_irq(&pDevice->lock);
445 if (pDevice->bLinkPass &&
446 memcmp(pMgmt->abyCurrSSID,
447 pMgmt->abyDesireSSID,
448 WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
449 bScheduleCommand((void *) pDevice,
450 WLAN_CMD_DISASSOCIATE, NULL);
451 } else {
452 pDevice->bLinkPass = false;
453 pMgmt->eCurrState = WMAC_STATE_IDLE;
454 memset(pMgmt->abyCurrBSSID, 0, 6);
457 ControlvMaskByte(pDevice,
458 MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY,
459 LEDSTS_STS, LEDSTS_SLOW);
461 netif_stop_queue(pDevice->dev);
463 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
465 if (!pDevice->bWPASuppWextEnabled)
466 bScheduleCommand((void *) pDevice,
467 WLAN_CMD_BSSID_SCAN,
468 pMgmt->abyDesireSSID);
470 bScheduleCommand((void *) pDevice,
471 WLAN_CMD_SSID,
472 NULL);
474 spin_unlock_irq(&pDevice->lock);
476 pDevice->bCommit = false;
479 return rc;
483 * Wireless Handler: get operation mode
485 int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
486 union iwreq_data *wrqu, char *extra)
488 struct vnt_private *pDevice = netdev_priv(dev);
489 __u32 *wmode = &wrqu->mode;
490 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
492 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n");
494 if (pMgmt == NULL)
495 return -EFAULT;
497 // If not managed, assume it's ad-hoc
498 switch (pMgmt->eConfigMode) {
499 case WMAC_CONFIG_ESS_STA:
500 *wmode = IW_MODE_INFRA;
501 break;
502 case WMAC_CONFIG_IBSS_STA:
503 *wmode = IW_MODE_ADHOC;
504 break;
505 case WMAC_CONFIG_AUTO:
506 *wmode = IW_MODE_INFRA;
507 break;
508 case WMAC_CONFIG_AP:
509 *wmode = IW_MODE_MASTER;
510 break;
511 default:
512 *wmode = IW_MODE_ADHOC;
515 return 0;
519 * Wireless Handler: get capability range
521 int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
522 union iwreq_data *wrqu, char *extra)
524 struct iw_point *wrq = &wrqu->data;
525 struct iw_range *range = (struct iw_range *)extra;
526 int i;
527 int k;
528 u8 abySupportedRates[13] = {
529 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
530 0x60, 0x6C, 0x90
533 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
534 if (wrq->pointer) {
535 wrq->length = sizeof(struct iw_range);
536 memset(range, 0, sizeof(struct iw_range));
537 range->min_nwid = 0x0000;
538 range->max_nwid = 0x0000;
539 range->num_channels = 14;
540 // Should be based on cap_rid.country to give only
541 // what the current card support
542 k = 0;
543 for (i = 0; i < 14; i++) {
544 range->freq[k].i = i + 1; // List index
545 range->freq[k].m = frequency_list[i] * 100000;
546 range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
548 range->num_frequency = k;
549 // Hum... Should put the right values there
550 range->max_qual.qual = 100;
551 range->max_qual.level = 0;
552 range->max_qual.noise = 0;
553 range->sensitivity = 255;
555 for (i = 0; i < 13; i++) {
556 range->bitrate[i] = abySupportedRates[i] * 500000;
557 if (range->bitrate[i] == 0)
558 break;
560 range->num_bitrates = i;
562 // Set an indication of the max TCP throughput
563 // in bit/s that we can expect using this interface.
564 // May be use for QoS stuff... Jean II
565 if (i > 2)
566 range->throughput = 5 * 1000 * 1000;
567 else
568 range->throughput = 1.5 * 1000 * 1000;
570 range->min_rts = 0;
571 range->max_rts = 2312;
572 range->min_frag = 256;
573 range->max_frag = 2312;
575 // the encoding capabilities
576 range->num_encoding_sizes = 3;
577 // 64(40) bits WEP
578 range->encoding_size[0] = 5;
579 // 128(104) bits WEP
580 range->encoding_size[1] = 13;
581 // 256 bits for WPA-PSK
582 range->encoding_size[2] = 32;
583 // 4 keys are allowed
584 range->max_encoding_tokens = 4;
586 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
587 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
589 range->min_pmp = 0;
590 range->max_pmp = 1000000; // 1 secs
591 range->min_pmt = 0;
592 range->max_pmt = 1000000; // 1 secs
593 range->pmp_flags = IW_POWER_PERIOD;
594 range->pmt_flags = IW_POWER_TIMEOUT;
595 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
597 // Transmit Power - values are in mW
598 range->txpower[0] = 100;
599 range->num_txpower = 1;
600 range->txpower_capa = IW_TXPOW_MWATT;
601 range->we_version_source = WIRELESS_EXT;
602 range->we_version_compiled = WIRELESS_EXT;
603 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
604 range->retry_flags = IW_RETRY_LIMIT;
605 range->r_time_flags = IW_RETRY_LIFETIME;
606 range->min_retry = 1;
607 range->max_retry = 65535;
608 range->min_r_time = 1024;
609 range->max_r_time = 65535 * 1024;
610 // Experimental measurements - boundary 11/5.5 Mb/s
611 // Note : with or without the (local->rssi), results
612 // are somewhat different. - Jean II
613 range->avg_qual.qual = 6;
614 range->avg_qual.level = 176; // -80 dBm
615 range->avg_qual.noise = 0;
618 return 0;
622 * Wireless Handler : set ap mac address
624 int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
625 union iwreq_data *wrqu, char *extra)
627 struct vnt_private *pDevice = netdev_priv(dev);
628 struct sockaddr *wrq = &wrqu->ap_addr;
629 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
630 int rc = 0;
631 u8 ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
633 PRINT_K(" SIOCSIWAP\n");
635 if (pMgmt == NULL)
636 return -EFAULT;
638 if (wrq->sa_family != ARPHRD_ETHER) {
639 rc = -EINVAL;
640 } else {
641 memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
642 // mike: add
643 if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
644 (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) {
645 PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
646 return rc;
648 // mike add: if desired AP is hidden ssid(there are
649 // two same BSSID in list), then ignore,because you
650 // don't known which one to be connect with??
652 unsigned ii;
653 unsigned uSameBssidNum = 0;
654 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
655 if (pMgmt->sBSSList[ii].bActive &&
656 ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
657 pMgmt->abyDesireBSSID)) {
658 uSameBssidNum++;
661 if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
662 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
663 return rc;
667 if (pDevice->flags & DEVICE_FLAGS_OPENED)
668 pDevice->bCommit = true;
670 return rc;
674 * Wireless Handler: get ap mac address
676 int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
677 union iwreq_data *wrqu, char *extra)
679 struct vnt_private *pDevice = netdev_priv(dev);
680 struct sockaddr *wrq = &wrqu->ap_addr;
681 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
683 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n");
685 if (pMgmt == NULL)
686 return -EFAULT;
688 memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
690 if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
691 memset(wrq->sa_data, 0, 6);
693 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
694 memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
696 wrq->sa_family = ARPHRD_ETHER;
697 return 0;
701 * Wireless Handler: get ap list
703 int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
704 union iwreq_data *wrqu, char *extra)
706 struct iw_point *wrq = &wrqu->data;
707 struct sockaddr *sock;
708 struct iw_quality *qual;
709 struct vnt_private *pDevice = netdev_priv(dev);
710 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
711 PKnownBSS pBSS = &pMgmt->sBSSList[0];
712 int ii;
713 int jj;
715 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n");
716 /* Only super-user can see AP list */
718 if (pBSS == NULL)
719 return -ENODEV;
721 if (!capable(CAP_NET_ADMIN))
722 return -EPERM;
724 if (!wrq->pointer)
725 return -EINVAL;
727 sock = kzalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
728 if (sock == NULL)
729 return -ENOMEM;
730 qual = kzalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
731 if (qual == NULL) {
732 kfree(sock);
733 return -ENOMEM;
736 for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
737 if (!pBSS[ii].bActive)
738 continue;
739 if (jj >= IW_MAX_AP)
740 break;
741 memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6);
742 sock[jj].sa_family = ARPHRD_ETHER;
743 qual[jj].level = pBSS[ii].uRSSI;
744 qual[jj].qual = qual[jj].noise = 0;
745 qual[jj].updated = 2;
746 jj++;
749 wrq->flags = 1; /* Should be defined */
750 wrq->length = jj;
751 memcpy(extra, sock, sizeof(struct sockaddr) * jj);
752 memcpy(extra + sizeof(struct sockaddr) * jj, qual,
753 sizeof(struct iw_quality) * jj);
755 kfree(sock);
756 kfree(qual);
758 return 0;
762 * Wireless Handler: set essid
764 int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
765 union iwreq_data *wrqu, char *extra)
767 struct vnt_private *pDevice = netdev_priv(dev);
768 struct iw_point *wrq = &wrqu->essid;
769 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
770 PWLAN_IE_SSID pItemSSID;
772 if (pMgmt == NULL)
773 return -EFAULT;
775 if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
776 return -EINVAL;
778 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
780 pDevice->fWPA_Authened = false;
781 // Check if we asked for `any'
782 if (wrq->flags == 0) {
783 // Just send an empty SSID list
784 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
785 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
786 PRINT_K("set essid to 'any'\n");
787 // Unknown desired AP, so here need not associate??
788 return 0;
789 } else {
790 // Set the SSID
791 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
792 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
793 pItemSSID->byElementID = WLAN_EID_SSID;
795 memcpy(pItemSSID->abySSID, extra, wrq->length);
796 if (pItemSSID->abySSID[wrq->length] == '\0') {
797 if (wrq->length > 0)
798 pItemSSID->len = wrq->length;
799 } else {
800 pItemSSID->len = wrq->length;
802 PRINT_K("set essid to %s\n", pItemSSID->abySSID);
804 // mike: need clear desiredBSSID
805 if (pItemSSID->len == 0) {
806 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
807 return 0;
810 // Wext wil order another command of siwap to link
811 // with desired AP, so here need not associate??
812 if (pDevice->bWPASuppWextEnabled == true) {
813 /*******search if in hidden ssid mode ****/
814 PKnownBSS pCurr = NULL;
815 u8 abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
816 unsigned ii;
817 unsigned uSameBssidNum = 0;
819 memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID));
820 pCurr = BSSpSearchBSSList(pDevice, NULL,
821 abyTmpDesireSSID,
822 pDevice->eConfigPHYMode);
824 if (pCurr == NULL) {
825 PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
826 vResetCommandTimer((void *)pDevice);
827 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
828 bScheduleCommand((void *)pDevice,
829 WLAN_CMD_BSSID_SCAN,
830 pMgmt->abyDesireSSID);
831 bScheduleCommand((void *)pDevice,
832 WLAN_CMD_SSID,
833 pMgmt->abyDesireSSID);
834 } else { // mike: to find out if that desired SSID is a
835 // hidden-ssid AP, by means of judging if there
836 // are two same BSSID exist in list ?
837 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
838 if (pMgmt->sBSSList[ii].bActive &&
839 ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
840 pCurr->abyBSSID)) {
841 uSameBssidNum++;
844 if (uSameBssidNum >= 2) { // hit: desired AP is in hidden ssid mode!!!
845 PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
846 vResetCommandTimer((void *)pDevice);
847 pMgmt->eScanType = WMAC_SCAN_PASSIVE; // this scan type, you'll submit scan result!
848 bScheduleCommand((void *)pDevice,
849 WLAN_CMD_BSSID_SCAN,
850 pMgmt->abyDesireSSID);
851 bScheduleCommand((void *)pDevice,
852 WLAN_CMD_SSID,
853 pMgmt->abyDesireSSID);
856 return 0;
859 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID);
862 if (pDevice->flags & DEVICE_FLAGS_OPENED)
863 pDevice->bCommit = true;
865 return 0;
869 * Wireless Handler: get essid
871 int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
872 union iwreq_data *wrqu, char *extra)
874 struct vnt_private *pDevice = netdev_priv(dev);
875 struct iw_point *wrq = &wrqu->essid;
876 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
877 PWLAN_IE_SSID pItemSSID;
879 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n");
881 if (pMgmt == NULL)
882 return -EFAULT;
884 // Note: if wrq->u.data.flags != 0, we should get the relevant
885 // SSID from the SSID list...
887 // Get the current SSID
888 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
889 memcpy(extra, pItemSSID->abySSID, pItemSSID->len);
890 extra[pItemSSID->len] = '\0';
892 wrq->length = pItemSSID->len;
893 wrq->flags = 1; // active
895 return 0;
899 * Wireless Handler: set data rate
901 int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
902 union iwreq_data *wrqu, char *extra)
904 struct vnt_private *pDevice = netdev_priv(dev);
905 struct iw_param *wrq = &wrqu->bitrate;
906 int rc = 0;
907 u8 brate = 0;
908 int i;
909 u8 abySupportedRates[13] = {
910 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
911 0x60, 0x6C, 0x90
914 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n");
915 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
916 rc = -EINVAL;
917 return rc;
920 // First: get a valid bit rate value
922 // Which type of value
923 if ((wrq->value < 13) && (wrq->value >= 0)) {
924 // Setting by rate index
925 // Find value in the magic rate table
926 brate = wrq->value;
927 } else {
928 // Setting by frequency value
929 u8 normvalue = (u8)(wrq->value/500000);
931 // Check if rate is valid
932 for (i = 0; i < 13; i++) {
933 if (normvalue == abySupportedRates[i]) {
934 brate = i;
935 break;
939 // -1 designed the max rate (mostly auto mode)
940 if (wrq->value == -1) {
941 // Get the highest available rate
942 for (i = 0; i < 13; i++) {
943 if (abySupportedRates[i] == 0)
944 break;
946 if (i != 0)
947 brate = i - 1;
950 // Check that it is valid
951 // brate is index of abySupportedRates[]
952 if (brate > 13) {
953 rc = -EINVAL;
954 return rc;
957 // Now, check if we want a fixed or auto value
958 if (wrq->fixed != 0) {
959 // Fixed mode
960 // One rate, fixed
961 pDevice->bFixRate = true;
962 if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) {
963 pDevice->uConnectionRate = 3;
964 } else {
965 pDevice->uConnectionRate = brate;
966 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate);
968 } else {
969 pDevice->bFixRate = false;
970 pDevice->uConnectionRate = 13;
973 return rc;
977 * Wireless Handler: get data rate
979 int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
980 union iwreq_data *wrqu, char *extra)
982 struct vnt_private *pDevice = netdev_priv(dev);
983 struct iw_param *wrq = &wrqu->bitrate;
984 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
986 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n");
988 if (pMgmt == NULL)
989 return -EFAULT;
992 u8 abySupportedRates[13] = {
993 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30,
994 0x48, 0x60, 0x6C, 0x90
996 int brate = 0;
998 if (pDevice->uConnectionRate < 13) {
999 brate = abySupportedRates[pDevice->uConnectionRate];
1000 } else {
1001 if (pDevice->byBBType == BB_TYPE_11B)
1002 brate = 0x16;
1003 if (pDevice->byBBType == BB_TYPE_11G)
1004 brate = 0x6C;
1005 if (pDevice->byBBType == BB_TYPE_11A)
1006 brate = 0x6C;
1008 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1009 if (pDevice->byBBType == BB_TYPE_11B)
1010 brate = 0x16;
1011 if (pDevice->byBBType == BB_TYPE_11G)
1012 brate = 0x6C;
1013 if (pDevice->byBBType == BB_TYPE_11A)
1014 brate = 0x6C;
1016 if (pDevice->uConnectionRate == 13)
1017 brate = abySupportedRates[pDevice->wCurrentRate];
1018 wrq->value = brate * 500000;
1019 // If more than one rate, set auto
1020 if (pDevice->bFixRate == true)
1021 wrq->fixed = true;
1024 return 0;
1028 * Wireless Handler: set rts threshold
1030 int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
1031 union iwreq_data *wrqu, char *extra)
1033 struct vnt_private *pDevice = netdev_priv(dev);
1034 struct iw_param *wrq = &wrqu->rts;
1036 if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
1037 return -EINVAL;
1039 else if (wrq->disabled)
1040 pDevice->wRTSThreshold = 2312;
1041 else
1042 pDevice->wRTSThreshold = wrq->value;
1044 return 0;
1048 * Wireless Handler: get rts
1050 int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
1051 union iwreq_data *wrqu, char *extra)
1053 struct vnt_private *pDevice = netdev_priv(dev);
1054 struct iw_param *wrq = &wrqu->rts;
1056 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n");
1057 wrq->value = pDevice->wRTSThreshold;
1058 wrq->disabled = (wrq->value >= 2312);
1059 wrq->fixed = 1;
1060 return 0;
1064 * Wireless Handler: set fragment threshold
1066 int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
1067 union iwreq_data *wrqu, char *extra)
1069 struct vnt_private *pDevice = netdev_priv(dev);
1070 struct iw_param *wrq = &wrqu->frag;
1071 int rc = 0;
1072 int fthr = wrq->value;
1074 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n");
1076 if (wrq->disabled)
1077 fthr = 2312;
1078 if ((fthr < 256) || (fthr > 2312)) {
1079 rc = -EINVAL;
1080 } else {
1081 fthr &= ~0x1; // Get an even value
1082 pDevice->wFragmentationThreshold = (u16)fthr;
1084 return rc;
1088 * Wireless Handler: get fragment threshold
1090 int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
1091 union iwreq_data *wrqu, char *extra)
1093 struct vnt_private *pDevice = netdev_priv(dev);
1094 struct iw_param *wrq = &wrqu->frag;
1096 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n");
1097 wrq->value = pDevice->wFragmentationThreshold;
1098 wrq->disabled = (wrq->value >= 2312);
1099 wrq->fixed = 1;
1100 return 0;
1104 * Wireless Handler: set retry threshold
1106 int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
1107 union iwreq_data *wrqu, char *extra)
1109 struct vnt_private *pDevice = netdev_priv(dev);
1110 struct iw_param *wrq = &wrqu->retry;
1111 int rc = 0;
1113 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n");
1115 if (wrq->disabled) {
1116 rc = -EINVAL;
1117 return rc;
1120 if (wrq->flags & IW_RETRY_LIMIT) {
1121 if (wrq->flags & IW_RETRY_MAX) {
1122 pDevice->byLongRetryLimit = wrq->value;
1123 } else if (wrq->flags & IW_RETRY_MIN) {
1124 pDevice->byShortRetryLimit = wrq->value;
1125 } else {
1126 // No modifier : set both
1127 pDevice->byShortRetryLimit = wrq->value;
1128 pDevice->byLongRetryLimit = wrq->value;
1131 if (wrq->flags & IW_RETRY_LIFETIME)
1132 pDevice->wMaxTransmitMSDULifetime = wrq->value;
1133 return rc;
1137 * Wireless Handler: get retry threshold
1139 int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
1140 union iwreq_data *wrqu, char *extra)
1142 struct vnt_private *pDevice = netdev_priv(dev);
1143 struct iw_param *wrq = &wrqu->retry;
1144 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n");
1145 wrq->disabled = 0; // Can't be disabled
1147 // Note: by default, display the min retry number
1148 if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1149 wrq->flags = IW_RETRY_LIFETIME;
1150 wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; // ms
1151 } else if ((wrq->flags & IW_RETRY_MAX)) {
1152 wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1153 wrq->value = (int)pDevice->byLongRetryLimit;
1154 } else {
1155 wrq->flags = IW_RETRY_LIMIT;
1156 wrq->value = (int)pDevice->byShortRetryLimit;
1157 if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
1158 wrq->flags |= IW_RETRY_MIN;
1160 return 0;
1164 * Wireless Handler: set encode mode
1166 int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
1167 union iwreq_data *wrqu, char *extra)
1169 struct vnt_private *pDevice = netdev_priv(dev);
1170 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1171 struct iw_point *wrq = &wrqu->encoding;
1172 u32 dwKeyIndex = (u32)(wrq->flags & IW_ENCODE_INDEX);
1173 int ii;
1174 int uu;
1175 int rc = 0;
1176 int index = (wrq->flags & IW_ENCODE_INDEX);
1178 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n");
1180 if (pMgmt == NULL)
1181 return -EFAULT;
1183 // Check the size of the key
1184 if (wrq->length > WLAN_WEP232_KEYLEN) {
1185 rc = -EINVAL;
1186 return rc;
1189 if (dwKeyIndex > WLAN_WEP_NKEYS) {
1190 rc = -EINVAL;
1191 return rc;
1194 if (dwKeyIndex > 0)
1195 dwKeyIndex--;
1197 // Send the key to the card
1198 if (wrq->length > 0) {
1199 if (wrq->length == WLAN_WEP232_KEYLEN) {
1200 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
1201 } else if (wrq->length == WLAN_WEP104_KEYLEN) {
1202 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
1203 } else if (wrq->length == WLAN_WEP40_KEYLEN) {
1204 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
1206 memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
1207 memcpy(pDevice->abyKey, extra, wrq->length);
1209 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
1210 for (ii = 0; ii < wrq->length; ii++)
1211 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
1213 if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1214 spin_lock_irq(&pDevice->lock);
1215 KeybSetDefaultKey(pDevice,
1216 &(pDevice->sKey),
1217 dwKeyIndex | (1 << 31),
1218 wrq->length, NULL,
1219 pDevice->abyKey,
1220 KEY_CTL_WEP);
1221 spin_unlock_irq(&pDevice->lock);
1223 pDevice->byKeyIndex = (u8)dwKeyIndex;
1224 pDevice->uKeyLength = wrq->length;
1225 pDevice->bTransmitKey = true;
1226 pDevice->bEncryptionEnable = true;
1227 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1229 // Do we want to just set the transmit key index?
1230 if (index < 4) {
1231 pDevice->byKeyIndex = index;
1232 } else if (!(wrq->flags & IW_ENCODE_MODE)) {
1233 rc = -EINVAL;
1234 return rc;
1237 // Read the flags
1238 if (wrq->flags & IW_ENCODE_DISABLED) {
1239 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
1240 pMgmt->bShareKeyAlgorithm = false;
1241 pDevice->bEncryptionEnable = false;
1242 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1243 if (pDevice->flags & DEVICE_FLAGS_OPENED) {
1244 spin_lock_irq(&pDevice->lock);
1245 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
1246 MACvDisableKeyEntry(pDevice, uu);
1247 spin_unlock_irq(&pDevice->lock);
1250 if (wrq->flags & IW_ENCODE_RESTRICTED) {
1251 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
1252 pMgmt->bShareKeyAlgorithm = true;
1254 if (wrq->flags & IW_ENCODE_OPEN) {
1255 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
1256 pMgmt->bShareKeyAlgorithm = false;
1259 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
1261 return rc;
1264 int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
1265 union iwreq_data *wrqu, char *extra)
1267 struct vnt_private *pDevice = netdev_priv(dev);
1268 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1269 struct iw_point *wrq = &wrqu->encoding;
1270 char abyKey[WLAN_WEP232_KEYLEN];
1272 unsigned index = (unsigned)(wrq->flags & IW_ENCODE_INDEX);
1273 PSKeyItem pKey = NULL;
1275 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1277 if (pMgmt == NULL)
1278 return -EFAULT;
1280 if (index > WLAN_WEP_NKEYS)
1281 return -EINVAL;
1282 if (index < 1) { // get default key
1283 if (pDevice->byKeyIndex < WLAN_WEP_NKEYS)
1284 index = pDevice->byKeyIndex;
1285 else
1286 index = 0;
1287 } else {
1288 index--;
1291 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1292 // Check encryption mode
1293 wrq->flags = IW_ENCODE_NOKEY;
1294 // Is WEP enabled ???
1295 if (pDevice->bEncryptionEnable)
1296 wrq->flags |= IW_ENCODE_ENABLED;
1297 else
1298 wrq->flags |= IW_ENCODE_DISABLED;
1300 if (pMgmt->bShareKeyAlgorithm)
1301 wrq->flags |= IW_ENCODE_RESTRICTED;
1302 else
1303 wrq->flags |= IW_ENCODE_OPEN;
1304 wrq->length = 0;
1306 if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled ||
1307 pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) { // get wpa pairwise key
1308 if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) {
1309 wrq->length = pKey->uKeyLength;
1310 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
1311 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
1313 } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (u8)index, &pKey)) {
1314 wrq->length = pKey->uKeyLength;
1315 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
1316 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
1319 wrq->flags |= index + 1;
1320 return 0;
1324 * Wireless Handler: set power mode
1326 int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
1327 union iwreq_data *wrqu, char *extra)
1329 struct vnt_private *pDevice = netdev_priv(dev);
1330 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1331 struct iw_param *wrq = &wrqu->power;
1332 int rc = 0;
1334 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n");
1336 if (pMgmt == NULL)
1337 return -EFAULT;
1339 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1340 rc = -EINVAL;
1341 return rc;
1344 spin_lock_irq(&pDevice->lock);
1346 if (wrq->disabled) {
1347 pDevice->ePSMode = WMAC_POWER_CAM;
1348 PSvDisablePowerSaving(pDevice);
1349 spin_unlock_irq(&pDevice->lock);
1350 return rc;
1352 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1353 pDevice->ePSMode = WMAC_POWER_FAST;
1354 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
1356 } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
1357 pDevice->ePSMode = WMAC_POWER_FAST;
1358 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
1361 spin_unlock_irq(&pDevice->lock);
1363 switch (wrq->flags & IW_POWER_MODE) {
1364 case IW_POWER_UNICAST_R:
1365 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n");
1366 rc = -EINVAL;
1367 break;
1368 case IW_POWER_ALL_R:
1369 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n");
1370 rc = -EINVAL;
1371 case IW_POWER_ON:
1372 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n");
1373 break;
1374 default:
1375 rc = -EINVAL;
1378 return rc;
1382 * Wireless Handler: get power mode
1384 int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
1385 union iwreq_data *wrqu, char *extra)
1387 struct vnt_private *pDevice = netdev_priv(dev);
1388 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1389 struct iw_param *wrq = &wrqu->power;
1390 int mode = pDevice->ePSMode;
1392 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
1394 if (pMgmt == NULL)
1395 return -EFAULT;
1397 if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
1398 return 0;
1400 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1401 wrq->value = (int)((pMgmt->wListenInterval *
1402 pMgmt->wCurrBeaconPeriod) / 100);
1403 wrq->flags = IW_POWER_TIMEOUT;
1404 } else {
1405 wrq->value = (int)((pMgmt->wListenInterval *
1406 pMgmt->wCurrBeaconPeriod) / 100);
1407 wrq->flags = IW_POWER_PERIOD;
1410 wrq->flags |= IW_POWER_ALL_R;
1411 return 0;
1415 * Wireless Handler: get Sensitivity
1417 int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
1418 union iwreq_data *wrqu, char *extra)
1420 struct vnt_private *pDevice = netdev_priv(dev);
1421 struct iw_param *wrq = &wrqu->sens;
1422 long ldBm;
1424 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
1425 if (pDevice->bLinkPass == true) {
1426 RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
1427 wrq->value = ldBm;
1428 } else {
1429 wrq->value = 0;
1431 wrq->disabled = (wrq->value == 0);
1432 wrq->fixed = 1;
1433 return 0;
1436 int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
1437 union iwreq_data *wrqu, char *extra)
1439 struct vnt_private *pDevice = netdev_priv(dev);
1440 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1441 struct iw_param *wrq = &wrqu->param;
1442 int ret = 0;
1443 static int wpa_version = 0; // must be static to save the last value, einsn liu
1444 static int pairwise = 0;
1446 if (pMgmt == NULL)
1447 return -EFAULT;
1449 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
1450 switch (wrq->flags & IW_AUTH_INDEX) {
1451 case IW_AUTH_WPA_VERSION:
1452 wpa_version = wrq->value;
1453 if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
1454 PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
1455 } else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) {
1456 PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
1457 } else {
1458 PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
1460 break;
1461 case IW_AUTH_CIPHER_PAIRWISE:
1462 pairwise = wrq->value;
1463 PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
1464 if (pairwise == IW_AUTH_CIPHER_CCMP) {
1465 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1466 } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
1467 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1468 } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
1469 pairwise == IW_AUTH_CIPHER_WEP104) {
1470 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1471 } else if (pairwise == IW_AUTH_CIPHER_NONE) {
1472 // do nothing, einsn liu
1473 } else {
1474 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1476 break;
1477 case IW_AUTH_CIPHER_GROUP:
1478 PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value);
1479 if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
1480 break;
1481 if (pairwise == IW_AUTH_CIPHER_NONE) {
1482 if (wrq->value == IW_AUTH_CIPHER_CCMP)
1483 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
1484 else
1485 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
1487 break;
1488 case IW_AUTH_KEY_MGMT:
1489 PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version, wrq->value);
1490 if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) {
1491 if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
1492 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1493 else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
1494 } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
1495 if (wrq->value == 0) {
1496 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
1497 } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
1498 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
1499 } else {
1500 pMgmt->eAuthenMode = WMAC_AUTH_WPA;
1502 break;
1503 case IW_AUTH_TKIP_COUNTERMEASURES:
1504 break; /* FIXME */
1505 case IW_AUTH_DROP_UNENCRYPTED:
1506 break;
1507 case IW_AUTH_80211_AUTH_ALG:
1508 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value);
1509 if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM)
1510 pMgmt->bShareKeyAlgorithm = false;
1511 else if (wrq->value == IW_AUTH_ALG_SHARED_KEY)
1512 pMgmt->bShareKeyAlgorithm = true;
1513 break;
1514 case IW_AUTH_WPA_ENABLED:
1515 break;
1516 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1517 break;
1518 case IW_AUTH_ROAMING_CONTROL:
1519 ret = -EOPNOTSUPP;
1520 break;
1521 case IW_AUTH_PRIVACY_INVOKED:
1522 pDevice->bEncryptionEnable = !!wrq->value;
1523 if (pDevice->bEncryptionEnable == false) {
1524 wpa_version = 0;
1525 pairwise = 0;
1526 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1527 pMgmt->bShareKeyAlgorithm = false;
1528 pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
1529 PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
1531 break;
1532 default:
1533 PRINT_K("iwctl_siwauth: not supported %x\n", wrq->flags);
1534 ret = -EOPNOTSUPP;
1535 break;
1537 return ret;
1540 int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
1541 union iwreq_data *wrqu, char *extra)
1543 return -EOPNOTSUPP;
1546 int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
1547 union iwreq_data *wrqu, char *extra)
1549 struct vnt_private *pDevice = netdev_priv(dev);
1550 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1551 struct iw_point *wrq = &wrqu->data;
1552 int ret = 0;
1554 if (pMgmt == NULL)
1555 return -EFAULT;
1557 if (wrq->length) {
1558 if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
1559 ret = -EINVAL;
1560 goto out;
1562 if (wrq->length > MAX_WPA_IE_LEN) {
1563 ret = -ENOMEM;
1564 goto out;
1566 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1568 memcpy(pMgmt->abyWPAIE, extra, wrq->length);
1569 pMgmt->wWPAIELen = wrq->length;
1570 } else {
1571 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1572 pMgmt->wWPAIELen = 0;
1575 out: // not completely ...not necessary in wpa_supplicant 0.5.8
1576 return ret;
1579 int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
1580 union iwreq_data *wrqu, char *extra)
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;
1588 if (pMgmt == NULL)
1589 return -EFAULT;
1591 wrq->length = 0;
1592 if (pMgmt->wWPAIELen > 0) {
1593 wrq->length = pMgmt->wWPAIELen;
1595 if (pMgmt->wWPAIELen <= space)
1596 memcpy(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
1597 else
1598 ret = -E2BIG;
1600 return ret;
1603 int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
1604 union iwreq_data *wrqu, char *extra)
1606 struct vnt_private *pDevice = netdev_priv(dev);
1607 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1608 struct iw_point *wrq = &wrqu->encoding;
1609 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
1610 struct viawget_wpa_param *param = NULL;
1611 // original member
1612 wpa_alg alg_name;
1613 u8 addr[6];
1614 int key_idx;
1615 int set_tx = 0;
1616 u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
1617 u8 key[64];
1618 size_t seq_len = 0;
1619 size_t key_len = 0;
1620 u8 *buf;
1621 u8 key_array[64];
1622 int ret = 0;
1624 PRINT_K("SIOCSIWENCODEEXT......\n");
1626 if (pMgmt == NULL)
1627 return -EFAULT;
1629 if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
1630 return -ENODEV;
1632 buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
1633 if (buf == NULL)
1634 return -ENOMEM;
1636 param = (struct viawget_wpa_param *)buf;
1638 // recover alg_name
1639 switch (ext->alg) {
1640 case IW_ENCODE_ALG_NONE:
1641 alg_name = WPA_ALG_NONE;
1642 break;
1643 case IW_ENCODE_ALG_WEP:
1644 alg_name = WPA_ALG_WEP;
1645 break;
1646 case IW_ENCODE_ALG_TKIP:
1647 alg_name = WPA_ALG_TKIP;
1648 break;
1649 case IW_ENCODE_ALG_CCMP:
1650 alg_name = WPA_ALG_CCMP;
1651 break;
1652 default:
1653 PRINT_K("Unknown alg = %d\n", ext->alg);
1654 ret = -ENOMEM;
1655 goto error;
1657 // recover addr
1658 memcpy(addr, ext->addr.sa_data, ETH_ALEN);
1659 // recover key_idx
1660 key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
1661 // recover set_tx
1662 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1663 set_tx = 1;
1664 // recover seq,seq_len
1665 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1666 seq_len = IW_ENCODE_SEQ_MAX_SIZE;
1667 memcpy(seq, ext->rx_seq, seq_len);
1669 // recover key,key_len
1670 if (ext->key_len) {
1671 key_len = ext->key_len;
1672 memcpy(key, &ext->key[0], key_len);
1674 memset(key_array, 0, 64);
1675 if (key_len > 0) {
1676 memcpy(key_array, key, key_len);
1677 if (key_len == 32) {
1678 // notice ! the oder
1679 memcpy(&key_array[16], &key[24], 8);
1680 memcpy(&key_array[24], &key[16], 8);
1684 /**************Translate iw_encode_ext to viawget_wpa_param****************/
1685 memcpy(param->addr, addr, ETH_ALEN);
1686 param->u.wpa_key.alg_name = (int)alg_name;
1687 param->u.wpa_key.set_tx = set_tx;
1688 param->u.wpa_key.key_index = key_idx;
1689 param->u.wpa_key.key_len = key_len;
1690 param->u.wpa_key.key = (u8 *)key_array;
1691 param->u.wpa_key.seq = (u8 *)seq;
1692 param->u.wpa_key.seq_len = seq_len;
1694 /****set if current action is Network Manager count?? */
1695 /****this method is so foolish,but there is no other way??? */
1696 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
1697 if (param->u.wpa_key.key_index == 0) {
1698 pDevice->bwextstep0 = true;
1700 if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
1701 pDevice->bwextstep0 = false;
1702 pDevice->bwextstep1 = true;
1704 if ((pDevice->bwextstep1 == true) && (param->u.wpa_key.key_index == 2)) {
1705 pDevice->bwextstep1 = false;
1706 pDevice->bwextstep2 = true;
1708 if ((pDevice->bwextstep2 == true) && (param->u.wpa_key.key_index == 3)) {
1709 pDevice->bwextstep2 = false;
1710 pDevice->bwextstep3 = true;
1713 if (pDevice->bwextstep3 == true) {
1714 PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
1715 pDevice->bwextstep0 = false;
1716 pDevice->bwextstep1 = false;
1717 pDevice->bwextstep2 = false;
1718 pDevice->bwextstep3 = false;
1719 pDevice->bWPASuppWextEnabled = true;
1720 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
1721 KeyvInitTable(pDevice, &pDevice->sKey);
1723 /*******/
1724 spin_lock_irq(&pDevice->lock);
1725 ret = wpa_set_keys(pDevice, param);
1726 spin_unlock_irq(&pDevice->lock);
1728 error:
1729 kfree(buf);
1730 return ret;
1733 int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
1734 union iwreq_data *wrqu, char *extra)
1736 return -EOPNOTSUPP;
1739 int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
1740 union iwreq_data *wrqu, char *extra)
1742 struct vnt_private *pDevice = netdev_priv(dev);
1743 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1744 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1745 int ret = 0;
1747 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
1749 if (pMgmt == NULL)
1750 return -EFAULT;
1752 if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
1753 ret = -EINVAL;
1754 return ret;
1756 switch (mlme->cmd) {
1757 case IW_MLME_DEAUTH:
1758 case IW_MLME_DISASSOC:
1759 if (pDevice->bLinkPass == true) {
1760 PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
1761 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE,
1762 NULL);
1764 break;
1765 default:
1766 ret = -EOPNOTSUPP;
1768 return ret;
1771 static int iwctl_config_commit(struct net_device *dev,
1772 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1774 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SIOCSIWCOMMIT\n");
1776 return 0;
1779 static const iw_handler iwctl_handler[] = {
1780 IW_HANDLER(SIOCSIWCOMMIT, iwctl_config_commit),
1781 IW_HANDLER(SIOCGIWNAME, iwctl_giwname),
1782 IW_HANDLER(SIOCSIWFREQ, iwctl_siwfreq),
1783 IW_HANDLER(SIOCGIWFREQ, iwctl_giwfreq),
1784 IW_HANDLER(SIOCSIWMODE, iwctl_siwmode),
1785 IW_HANDLER(SIOCGIWMODE, iwctl_giwmode),
1786 IW_HANDLER(SIOCGIWSENS, iwctl_giwsens),
1787 IW_HANDLER(SIOCGIWRANGE, iwctl_giwrange),
1788 IW_HANDLER(SIOCSIWAP, iwctl_siwap),
1789 IW_HANDLER(SIOCGIWAP, iwctl_giwap),
1790 IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
1791 IW_HANDLER(SIOCGIWAPLIST, iwctl_giwaplist),
1792 IW_HANDLER(SIOCSIWSCAN, iwctl_siwscan),
1793 IW_HANDLER(SIOCGIWSCAN, iwctl_giwscan),
1794 IW_HANDLER(SIOCSIWESSID, iwctl_siwessid),
1795 IW_HANDLER(SIOCGIWESSID, iwctl_giwessid),
1796 IW_HANDLER(SIOCSIWRATE, iwctl_siwrate),
1797 IW_HANDLER(SIOCGIWRATE, iwctl_giwrate),
1798 IW_HANDLER(SIOCSIWRTS, iwctl_siwrts),
1799 IW_HANDLER(SIOCGIWRTS, iwctl_giwrts),
1800 IW_HANDLER(SIOCSIWFRAG, iwctl_siwfrag),
1801 IW_HANDLER(SIOCGIWFRAG, iwctl_giwfrag),
1802 IW_HANDLER(SIOCSIWRETRY, iwctl_siwretry),
1803 IW_HANDLER(SIOCGIWRETRY, iwctl_giwretry),
1804 IW_HANDLER(SIOCSIWENCODE, iwctl_siwencode),
1805 IW_HANDLER(SIOCGIWENCODE, iwctl_giwencode),
1806 IW_HANDLER(SIOCSIWPOWER, iwctl_siwpower),
1807 IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
1808 IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
1809 IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
1810 IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
1811 IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
1812 IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
1813 IW_HANDLER(SIOCGIWENCODEEXT, iwctl_giwencodeext)
1816 static const iw_handler iwctl_private_handler[] = {
1817 NULL, // SIOCIWFIRSTPRIV
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,