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