Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[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"
62c8526d 41#include "usbpipe.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;
21bba58a 60 vnt_rf_rssi_to_dbm(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;
21bba58a 238 vnt_rf_rssi_to_dbm(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
96f6975b 445 vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
5743fc81
MP
446
447 netif_stop_queue(pDevice->dev);
448
449 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
450
451 if (!pDevice->bWPASuppWextEnabled)
452 bScheduleCommand((void *) pDevice,
453 WLAN_CMD_BSSID_SCAN,
454 pMgmt->abyDesireSSID);
455
456 bScheduleCommand((void *) pDevice,
457 WLAN_CMD_SSID,
458 NULL);
5743fc81 459 }
e269fc2d 460 pDevice->bCommit = false;
5743fc81
MP
461 }
462
92b96797
FB
463 return rc;
464}
465
466/*
5a673637 467 * Wireless Handler: get operation mode
92b96797 468 */
5743fc81
MP
469int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
470 union iwreq_data *wrqu, char *extra)
92b96797 471{
da033bfd 472 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 473 __u32 *wmode = &wrqu->mode;
da033bfd 474 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
92b96797 475
5743fc81
MP
476 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n");
477
478 if (pMgmt == NULL)
479 return -EFAULT;
480
92b96797
FB
481 // If not managed, assume it's ad-hoc
482 switch (pMgmt->eConfigMode) {
483 case WMAC_CONFIG_ESS_STA:
484 *wmode = IW_MODE_INFRA;
485 break;
486 case WMAC_CONFIG_IBSS_STA:
48746d7f 487 *wmode = IW_MODE_ADHOC;
92b96797
FB
488 break;
489 case WMAC_CONFIG_AUTO:
490 *wmode = IW_MODE_INFRA;
491 break;
492 case WMAC_CONFIG_AP:
493 *wmode = IW_MODE_MASTER;
494 break;
495 default:
496 *wmode = IW_MODE_ADHOC;
497 }
5743fc81
MP
498
499 return 0;
92b96797
FB
500}
501
92b96797 502/*
5a673637 503 * Wireless Handler: get capability range
92b96797 504 */
5743fc81
MP
505int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
506 union iwreq_data *wrqu, char *extra)
92b96797 507{
5743fc81 508 struct iw_point *wrq = &wrqu->data;
bd4208e9 509 struct iw_range *range = (struct iw_range *)extra;
c91a8d5a
JJ
510 int i;
511 int k;
b902fbfe 512 u8 abySupportedRates[13] = {
c91a8d5a
JJ
513 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
514 0x60, 0x6C, 0x90
515 };
92b96797 516
48746d7f 517 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
92b96797
FB
518 if (wrq->pointer) {
519 wrq->length = sizeof(struct iw_range);
520 memset(range, 0, sizeof(struct iw_range));
521 range->min_nwid = 0x0000;
522 range->max_nwid = 0x0000;
523 range->num_channels = 14;
524 // Should be based on cap_rid.country to give only
5a673637 525 // what the current card support
92b96797 526 k = 0;
33d33e42 527 for (i = 0; i < 14; i++) {
92b96797
FB
528 range->freq[k].i = i + 1; // List index
529 range->freq[k].m = frequency_list[i] * 100000;
530 range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
531 }
532 range->num_frequency = k;
533 // Hum... Should put the right values there
48746d7f 534 range->max_qual.qual = 100;
92b96797
FB
535 range->max_qual.level = 0;
536 range->max_qual.noise = 0;
537 range->sensitivity = 255;
538
37f0777f 539 for (i = 0; i < 13; i++) {
92b96797 540 range->bitrate[i] = abySupportedRates[i] * 500000;
f269d1c2 541 if (range->bitrate[i] == 0)
92b96797
FB
542 break;
543 }
544 range->num_bitrates = i;
545
546 // Set an indication of the max TCP throughput
547 // in bit/s that we can expect using this interface.
548 // May be use for QoS stuff... Jean II
f269d1c2 549 if (i > 2)
92b96797
FB
550 range->throughput = 5 * 1000 * 1000;
551 else
552 range->throughput = 1.5 * 1000 * 1000;
553
554 range->min_rts = 0;
555 range->max_rts = 2312;
556 range->min_frag = 256;
557 range->max_frag = 2312;
558
48746d7f
JJ
559 // the encoding capabilities
560 range->num_encoding_sizes = 3;
561 // 64(40) bits WEP
562 range->encoding_size[0] = 5;
563 // 128(104) bits WEP
564 range->encoding_size[1] = 13;
565 // 256 bits for WPA-PSK
566 range->encoding_size[2] = 32;
567 // 4 keys are allowed
568 range->max_encoding_tokens = 4;
92b96797 569
48746d7f
JJ
570 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
571 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
92b96797 572
92b96797 573 range->min_pmp = 0;
5a673637 574 range->max_pmp = 1000000; // 1 secs
92b96797 575 range->min_pmt = 0;
5a673637 576 range->max_pmt = 1000000; // 1 secs
92b96797
FB
577 range->pmp_flags = IW_POWER_PERIOD;
578 range->pmt_flags = IW_POWER_TIMEOUT;
579 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
580
581 // Transmit Power - values are in mW
48746d7f 582 range->txpower[0] = 100;
92b96797
FB
583 range->num_txpower = 1;
584 range->txpower_capa = IW_TXPOW_MWATT;
dfc935ac 585 range->we_version_source = WIRELESS_EXT;
92b96797
FB
586 range->we_version_compiled = WIRELESS_EXT;
587 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
588 range->retry_flags = IW_RETRY_LIMIT;
589 range->r_time_flags = IW_RETRY_LIFETIME;
590 range->min_retry = 1;
591 range->max_retry = 65535;
592 range->min_r_time = 1024;
593 range->max_r_time = 65535 * 1024;
92b96797
FB
594 // Experimental measurements - boundary 11/5.5 Mb/s
595 // Note : with or without the (local->rssi), results
596 // are somewhat different. - Jean II
597 range->avg_qual.qual = 6;
5a673637 598 range->avg_qual.level = 176; // -80 dBm
92b96797 599 range->avg_qual.noise = 0;
92b96797 600 }
5743fc81
MP
601
602 return 0;
92b96797
FB
603}
604
92b96797
FB
605/*
606 * Wireless Handler : set ap mac address
607 */
921cd68b 608int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
5743fc81 609 union iwreq_data *wrqu, char *extra)
92b96797 610{
da033bfd 611 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 612 struct sockaddr *wrq = &wrqu->ap_addr;
da033bfd 613 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
48746d7f 614 int rc = 0;
b902fbfe 615 u8 ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
92b96797 616
5743fc81
MP
617 PRINT_K(" SIOCSIWAP\n");
618
619 if (pMgmt == NULL)
620 return -EFAULT;
92b96797 621
0c5c7901 622 if (wrq->sa_family != ARPHRD_ETHER) {
92b96797 623 rc = -EINVAL;
0c5c7901 624 } else {
92b96797 625 memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
5a673637 626 // mike: add
48746d7f 627 if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
37f0777f 628 (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) {
48746d7f
JJ
629 PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
630 return rc;
631 }
5a673637
JJ
632 // mike add: if desired AP is hidden ssid(there are
633 // two same BSSID in list), then ignore,because you
634 // don't known which one to be connect with??
48746d7f 635 {
c91a8d5a
JJ
636 unsigned ii;
637 unsigned uSameBssidNum = 0;
48746d7f
JJ
638 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
639 if (pMgmt->sBSSList[ii].bActive &&
8329419a
JP
640 ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
641 pMgmt->abyDesireBSSID)) {
48746d7f
JJ
642 uSameBssidNum++;
643 }
644 }
f269d1c2 645 if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
48746d7f
JJ
646 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
647 return rc;
648 }
649 }
650
8c3337fe 651 if (pDevice->flags & DEVICE_FLAGS_OPENED)
4e9b5e2b 652 pDevice->bCommit = true;
92b96797
FB
653 }
654 return rc;
655}
656
657/*
5a673637 658 * Wireless Handler: get ap mac address
92b96797 659 */
921cd68b 660int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
5743fc81 661 union iwreq_data *wrqu, char *extra)
92b96797 662{
da033bfd 663 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 664 struct sockaddr *wrq = &wrqu->ap_addr;
da033bfd 665 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
92b96797 666
5743fc81
MP
667 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n");
668
669 if (pMgmt == NULL)
670 return -EFAULT;
92b96797 671
48746d7f 672 memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
92b96797 673
e269fc2d 674 if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
48746d7f 675 memset(wrq->sa_data, 0, 6);
92b96797 676
8c3337fe 677 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
48746d7f 678 memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
92b96797
FB
679
680 wrq->sa_family = ARPHRD_ETHER;
92b96797 681 return 0;
92b96797
FB
682}
683
92b96797 684/*
5a673637 685 * Wireless Handler: get ap list
92b96797 686 */
921cd68b 687int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
5743fc81 688 union iwreq_data *wrqu, char *extra)
92b96797 689{
5743fc81 690 struct iw_point *wrq = &wrqu->data;
848ce511
MP
691 struct sockaddr *sock;
692 struct iw_quality *qual;
da033bfd
MP
693 struct vnt_private *pDevice = netdev_priv(dev);
694 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
848ce511 695 PKnownBSS pBSS = &pMgmt->sBSSList[0];
c91a8d5a
JJ
696 int ii;
697 int jj;
92b96797 698
848ce511
MP
699 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n");
700 /* Only super-user can see AP list */
92b96797 701
848ce511
MP
702 if (pBSS == NULL)
703 return -ENODEV;
92b96797 704
848ce511
MP
705 if (!capable(CAP_NET_ADMIN))
706 return -EPERM;
92b96797 707
848ce511
MP
708 if (!wrq->pointer)
709 return -EINVAL;
710
879ea7d3 711 sock = kcalloc(IW_MAX_AP, sizeof(struct sockaddr), GFP_KERNEL);
2a38e6fc
MP
712 if (sock == NULL)
713 return -ENOMEM;
879ea7d3 714 qual = kcalloc(IW_MAX_AP, sizeof(struct iw_quality), GFP_KERNEL);
2a38e6fc
MP
715 if (qual == NULL) {
716 kfree(sock);
848ce511 717 return -ENOMEM;
2a38e6fc 718 }
92b96797 719
848ce511
MP
720 for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
721 if (!pBSS[ii].bActive)
722 continue;
723 if (jj >= IW_MAX_AP)
724 break;
725 memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6);
726 sock[jj].sa_family = ARPHRD_ETHER;
727 qual[jj].level = pBSS[ii].uRSSI;
728 qual[jj].qual = qual[jj].noise = 0;
729 qual[jj].updated = 2;
730 jj++;
92b96797 731 }
848ce511
MP
732
733 wrq->flags = 1; /* Should be defined */
734 wrq->length = jj;
735 memcpy(extra, sock, sizeof(struct sockaddr) * jj);
736 memcpy(extra + sizeof(struct sockaddr) * jj, qual,
737 sizeof(struct iw_quality) * jj);
738
739 kfree(sock);
740 kfree(qual);
741
742 return 0;
92b96797
FB
743}
744
92b96797 745/*
5a673637 746 * Wireless Handler: set essid
92b96797 747 */
921cd68b 748int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
5743fc81 749 union iwreq_data *wrqu, char *extra)
92b96797 750{
da033bfd 751 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 752 struct iw_point *wrq = &wrqu->essid;
da033bfd 753 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
c91a8d5a 754 PWLAN_IE_SSID pItemSSID;
92b96797 755
5743fc81
MP
756 if (pMgmt == NULL)
757 return -EFAULT;
758
48746d7f
JJ
759 if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
760 return -EINVAL;
92b96797 761
48746d7f 762 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
92b96797 763
e269fc2d 764 pDevice->fWPA_Authened = false;
92b96797 765 // Check if we asked for `any'
f269d1c2 766 if (wrq->flags == 0) {
92b96797
FB
767 // Just send an empty SSID list
768 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
a96f5ba6 769 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
c744fd5f 770 PRINT_K("set essid to 'any'\n");
37f0777f 771 // Unknown desired AP, so here need not associate??
48746d7f 772 return 0;
92b96797
FB
773 } else {
774 // Set the SSID
775 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
48746d7f
JJ
776 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
777 pItemSSID->byElementID = WLAN_EID_SSID;
92b96797
FB
778
779 memcpy(pItemSSID->abySSID, extra, wrq->length);
dfc935ac 780 if (pItemSSID->abySSID[wrq->length] == '\0') {
a96f5ba6 781 if (wrq->length > 0)
dfc935ac 782 pItemSSID->len = wrq->length;
8c3337fe 783 } else {
48746d7f 784 pItemSSID->len = wrq->length;
8c3337fe 785 }
c744fd5f 786 PRINT_K("set essid to %s\n", pItemSSID->abySSID);
92b96797 787
5a673637 788 // mike: need clear desiredBSSID
a96f5ba6 789 if (pItemSSID->len == 0) {
37f0777f 790 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
48746d7f
JJ
791 return 0;
792 }
92b96797 793
5a673637
JJ
794 // Wext wil order another command of siwap to link
795 // with desired AP, so here need not associate??
4e9b5e2b 796 if (pDevice->bWPASuppWextEnabled == true) {
48746d7f 797 /*******search if in hidden ssid mode ****/
da06f7db 798 PKnownBSS pCurr = NULL;
b902fbfe 799 u8 abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
da06f7db
JJ
800 unsigned ii;
801 unsigned uSameBssidNum = 0;
802
37f0777f 803 memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID));
da06f7db
JJ
804 pCurr = BSSpSearchBSSList(pDevice, NULL,
805 abyTmpDesireSSID,
37f0777f 806 pDevice->eConfigPHYMode);
da06f7db 807
37f0777f 808 if (pCurr == NULL) {
da06f7db 809 PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
bd4208e9 810 vResetCommandTimer((void *)pDevice);
da06f7db 811 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
bd4208e9 812 bScheduleCommand((void *)pDevice,
da06f7db
JJ
813 WLAN_CMD_BSSID_SCAN,
814 pMgmt->abyDesireSSID);
bd4208e9 815 bScheduleCommand((void *)pDevice,
da06f7db
JJ
816 WLAN_CMD_SSID,
817 pMgmt->abyDesireSSID);
8c3337fe 818 } else { // mike: to find out if that desired SSID is a
5a673637
JJ
819 // hidden-ssid AP, by means of judging if there
820 // are two same BSSID exist in list ?
da06f7db
JJ
821 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
822 if (pMgmt->sBSSList[ii].bActive &&
8329419a
JP
823 ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
824 pCurr->abyBSSID)) {
da06f7db
JJ
825 uSameBssidNum++;
826 }
827 }
5a673637 828 if (uSameBssidNum >= 2) { // hit: desired AP is in hidden ssid mode!!!
da06f7db 829 PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
bd4208e9 830 vResetCommandTimer((void *)pDevice);
5a673637 831 pMgmt->eScanType = WMAC_SCAN_PASSIVE; // this scan type, you'll submit scan result!
bd4208e9 832 bScheduleCommand((void *)pDevice,
48746d7f
JJ
833 WLAN_CMD_BSSID_SCAN,
834 pMgmt->abyDesireSSID);
bd4208e9 835 bScheduleCommand((void *)pDevice,
48746d7f
JJ
836 WLAN_CMD_SSID,
837 pMgmt->abyDesireSSID);
838 }
48746d7f
JJ
839 }
840 return 0;
841 }
48746d7f 842
c744fd5f 843 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID);
92b96797
FB
844 }
845
8c3337fe 846 if (pDevice->flags & DEVICE_FLAGS_OPENED)
4e9b5e2b 847 pDevice->bCommit = true;
8c3337fe 848
92b96797
FB
849 return 0;
850}
851
92b96797 852/*
5a673637 853 * Wireless Handler: get essid
92b96797 854 */
5743fc81
MP
855int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
856 union iwreq_data *wrqu, char *extra)
92b96797 857{
da033bfd 858 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 859 struct iw_point *wrq = &wrqu->essid;
da033bfd 860 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
c91a8d5a 861 PWLAN_IE_SSID pItemSSID;
92b96797 862
5743fc81
MP
863 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n");
864
865 if (pMgmt == NULL)
866 return -EFAULT;
92b96797 867
5a673637
JJ
868 // Note: if wrq->u.data.flags != 0, we should get the relevant
869 // SSID from the SSID list...
92b96797
FB
870
871 // Get the current SSID
48746d7f 872 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
37f0777f 873 memcpy(extra, pItemSSID->abySSID, pItemSSID->len);
92b96797 874 extra[pItemSSID->len] = '\0';
465711b3 875
c744fd5f 876 wrq->length = pItemSSID->len;
92b96797 877 wrq->flags = 1; // active
5743fc81
MP
878
879 return 0;
92b96797
FB
880}
881
882/*
5a673637 883 * Wireless Handler: set data rate
92b96797 884 */
921cd68b 885int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
5743fc81 886 union iwreq_data *wrqu, char *extra)
92b96797 887{
da033bfd 888 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 889 struct iw_param *wrq = &wrqu->bitrate;
48746d7f 890 int rc = 0;
c91a8d5a
JJ
891 u8 brate = 0;
892 int i;
b902fbfe 893 u8 abySupportedRates[13] = {
c91a8d5a
JJ
894 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
895 0x60, 0x6C, 0x90
896 };
92b96797 897
c744fd5f 898 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n");
48746d7f
JJ
899 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
900 rc = -EINVAL;
901 return rc;
902 }
92b96797 903
5a673637 904 // First: get a valid bit rate value
92b96797
FB
905
906 // Which type of value
37f0777f 907 if ((wrq->value < 13) && (wrq->value >= 0)) {
92b96797
FB
908 // Setting by rate index
909 // Find value in the magic rate table
910 brate = wrq->value;
911 } else {
912 // Setting by frequency value
37f0777f 913 u8 normvalue = (u8)(wrq->value/500000);
92b96797
FB
914
915 // Check if rate is valid
37f0777f 916 for (i = 0; i < 13; i++) {
f269d1c2 917 if (normvalue == abySupportedRates[i]) {
92b96797
FB
918 brate = i;
919 break;
920 }
921 }
922 }
923 // -1 designed the max rate (mostly auto mode)
f269d1c2 924 if (wrq->value == -1) {
92b96797 925 // Get the highest available rate
37f0777f 926 for (i = 0; i < 13; i++) {
f269d1c2 927 if (abySupportedRates[i] == 0)
92b96797
FB
928 break;
929 }
f269d1c2 930 if (i != 0)
92b96797
FB
931 brate = i - 1;
932
933 }
934 // Check that it is valid
935 // brate is index of abySupportedRates[]
a96f5ba6 936 if (brate > 13) {
92b96797
FB
937 rc = -EINVAL;
938 return rc;
939 }
940
941 // Now, check if we want a fixed or auto value
f269d1c2 942 if (wrq->fixed != 0) {
92b96797
FB
943 // Fixed mode
944 // One rate, fixed
4e9b5e2b 945 pDevice->bFixRate = true;
37f0777f 946 if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) {
48746d7f 947 pDevice->uConnectionRate = 3;
8c3337fe 948 } else {
48746d7f 949 pDevice->uConnectionRate = brate;
c744fd5f 950 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate);
48746d7f 951 }
0c5c7901 952 } else {
e269fc2d 953 pDevice->bFixRate = false;
48746d7f
JJ
954 pDevice->uConnectionRate = 13;
955 }
92b96797
FB
956
957 return rc;
958}
959
960/*
5a673637 961 * Wireless Handler: get data rate
92b96797 962 */
5743fc81
MP
963int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
964 union iwreq_data *wrqu, char *extra)
92b96797 965{
da033bfd 966 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 967 struct iw_param *wrq = &wrqu->bitrate;
da033bfd 968 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
92b96797 969
5743fc81
MP
970 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n");
971
972 if (pMgmt == NULL)
973 return -EFAULT;
974
48746d7f 975 {
b902fbfe 976 u8 abySupportedRates[13] = {
c91a8d5a
JJ
977 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30,
978 0x48, 0x60, 0x6C, 0x90
979 };
48746d7f 980 int brate = 0;
c91a8d5a 981
92b96797 982 if (pDevice->uConnectionRate < 13) {
48746d7f 983 brate = abySupportedRates[pDevice->uConnectionRate];
8c3337fe 984 } else {
48746d7f
JJ
985 if (pDevice->byBBType == BB_TYPE_11B)
986 brate = 0x16;
987 if (pDevice->byBBType == BB_TYPE_11G)
988 brate = 0x6C;
989 if (pDevice->byBBType == BB_TYPE_11A)
990 brate = 0x6C;
991 }
48746d7f
JJ
992 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
993 if (pDevice->byBBType == BB_TYPE_11B)
994 brate = 0x16;
995 if (pDevice->byBBType == BB_TYPE_11G)
996 brate = 0x6C;
997 if (pDevice->byBBType == BB_TYPE_11A)
998 brate = 0x6C;
999 }
c744fd5f 1000 if (pDevice->uConnectionRate == 13)
48746d7f
JJ
1001 brate = abySupportedRates[pDevice->wCurrentRate];
1002 wrq->value = brate * 500000;
1003 // If more than one rate, set auto
4e9b5e2b
AM
1004 if (pDevice->bFixRate == true)
1005 wrq->fixed = true;
48746d7f 1006 }
5743fc81
MP
1007
1008 return 0;
92b96797
FB
1009}
1010
92b96797 1011/*
5a673637 1012 * Wireless Handler: set rts threshold
92b96797 1013 */
5743fc81
MP
1014int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
1015 union iwreq_data *wrqu, char *extra)
92b96797 1016{
da033bfd 1017 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 1018 struct iw_param *wrq = &wrqu->rts;
92b96797 1019
2fdde902
MPS
1020 if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
1021 return -EINVAL;
92b96797 1022
2fdde902
MPS
1023 else if (wrq->disabled)
1024 pDevice->wRTSThreshold = 2312;
2fdde902
MPS
1025 else
1026 pDevice->wRTSThreshold = wrq->value;
92b96797
FB
1027
1028 return 0;
1029}
1030
1031/*
5a673637 1032 * Wireless Handler: get rts
92b96797 1033 */
921cd68b 1034int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
5743fc81 1035 union iwreq_data *wrqu, char *extra)
92b96797 1036{
da033bfd 1037 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 1038 struct iw_param *wrq = &wrqu->rts;
92b96797 1039
5743fc81 1040 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n");
92b96797
FB
1041 wrq->value = pDevice->wRTSThreshold;
1042 wrq->disabled = (wrq->value >= 2312);
1043 wrq->fixed = 1;
92b96797
FB
1044 return 0;
1045}
1046
1047/*
5a673637 1048 * Wireless Handler: set fragment threshold
92b96797 1049 */
921cd68b 1050int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
5743fc81 1051 union iwreq_data *wrqu, char *extra)
92b96797 1052{
da033bfd 1053 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 1054 struct iw_param *wrq = &wrqu->frag;
48746d7f
JJ
1055 int rc = 0;
1056 int fthr = wrq->value;
92b96797 1057
5743fc81 1058 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n");
92b96797 1059
48746d7f 1060 if (wrq->disabled)
92b96797 1061 fthr = 2312;
f269d1c2 1062 if ((fthr < 256) || (fthr > 2312)) {
92b96797 1063 rc = -EINVAL;
8c3337fe 1064 } else {
5a673637 1065 fthr &= ~0x1; // Get an even value
48746d7f
JJ
1066 pDevice->wFragmentationThreshold = (u16)fthr;
1067 }
92b96797
FB
1068 return rc;
1069}
1070
1071/*
5a673637 1072 * Wireless Handler: get fragment threshold
92b96797 1073 */
921cd68b 1074int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
5743fc81 1075 union iwreq_data *wrqu, char *extra)
92b96797 1076{
da033bfd 1077 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 1078 struct iw_param *wrq = &wrqu->frag;
92b96797 1079
5743fc81 1080 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n");
92b96797
FB
1081 wrq->value = pDevice->wFragmentationThreshold;
1082 wrq->disabled = (wrq->value >= 2312);
1083 wrq->fixed = 1;
92b96797
FB
1084 return 0;
1085}
1086
92b96797 1087/*
5a673637 1088 * Wireless Handler: set retry threshold
92b96797 1089 */
921cd68b 1090int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
5743fc81 1091 union iwreq_data *wrqu, char *extra)
92b96797 1092{
da033bfd 1093 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 1094 struct iw_param *wrq = &wrqu->retry;
48746d7f 1095 int rc = 0;
92b96797 1096
5743fc81 1097 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n");
92b96797
FB
1098
1099 if (wrq->disabled) {
1100 rc = -EINVAL;
1101 return rc;
1102 }
1103
1104 if (wrq->flags & IW_RETRY_LIMIT) {
8c3337fe 1105 if (wrq->flags & IW_RETRY_MAX) {
92b96797 1106 pDevice->byLongRetryLimit = wrq->value;
8c3337fe 1107 } else if (wrq->flags & IW_RETRY_MIN) {
92b96797 1108 pDevice->byShortRetryLimit = wrq->value;
8c3337fe 1109 } else {
92b96797
FB
1110 // No modifier : set both
1111 pDevice->byShortRetryLimit = wrq->value;
1112 pDevice->byLongRetryLimit = wrq->value;
1113 }
1114 }
8c3337fe 1115 if (wrq->flags & IW_RETRY_LIFETIME)
92b96797 1116 pDevice->wMaxTransmitMSDULifetime = wrq->value;
92b96797
FB
1117 return rc;
1118}
1119
1120/*
5a673637 1121 * Wireless Handler: get retry threshold
92b96797 1122 */
921cd68b 1123int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
5743fc81 1124 union iwreq_data *wrqu, char *extra)
92b96797 1125{
da033bfd 1126 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81
MP
1127 struct iw_param *wrq = &wrqu->retry;
1128 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n");
5a673637 1129 wrq->disabled = 0; // Can't be disabled
92b96797 1130
5a673637 1131 // Note: by default, display the min retry number
f269d1c2 1132 if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
92b96797 1133 wrq->flags = IW_RETRY_LIFETIME;
5a673637 1134 wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; // ms
f269d1c2 1135 } else if ((wrq->flags & IW_RETRY_MAX)) {
92b96797
FB
1136 wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1137 wrq->value = (int)pDevice->byLongRetryLimit;
1138 } else {
1139 wrq->flags = IW_RETRY_LIMIT;
1140 wrq->value = (int)pDevice->byShortRetryLimit;
f269d1c2 1141 if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
92b96797
FB
1142 wrq->flags |= IW_RETRY_MIN;
1143 }
92b96797
FB
1144 return 0;
1145}
1146
92b96797 1147/*
5a673637 1148 * Wireless Handler: set encode mode
92b96797 1149 */
921cd68b 1150int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
5743fc81 1151 union iwreq_data *wrqu, char *extra)
92b96797 1152{
da033bfd
MP
1153 struct vnt_private *pDevice = netdev_priv(dev);
1154 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81
MP
1155 struct iw_point *wrq = &wrqu->encoding;
1156 u32 dwKeyIndex = (u32)(wrq->flags & IW_ENCODE_INDEX);
c91a8d5a 1157 int ii;
9190c4d2 1158 u8 uu;
c91a8d5a 1159 int rc = 0;
92b96797
FB
1160 int index = (wrq->flags & IW_ENCODE_INDEX);
1161
5743fc81
MP
1162 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n");
1163
1164 if (pMgmt == NULL)
1165 return -EFAULT;
92b96797
FB
1166
1167 // Check the size of the key
1168 if (wrq->length > WLAN_WEP232_KEYLEN) {
1169 rc = -EINVAL;
48746d7f 1170 return rc;
92b96797
FB
1171 }
1172
1173 if (dwKeyIndex > WLAN_WEP_NKEYS) {
1174 rc = -EINVAL;
48746d7f
JJ
1175 return rc;
1176 }
92b96797 1177
48746d7f 1178 if (dwKeyIndex > 0)
92b96797
FB
1179 dwKeyIndex--;
1180
1181 // Send the key to the card
1182 if (wrq->length > 0) {
4063d060 1183 if (wrq->length == WLAN_WEP232_KEYLEN) {
48746d7f 1184 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
4063d060 1185 } else if (wrq->length == WLAN_WEP104_KEYLEN) {
48746d7f 1186 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
8c3337fe 1187 } else if (wrq->length == WLAN_WEP40_KEYLEN) {
48746d7f
JJ
1188 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
1189 }
1190 memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
1191 memcpy(pDevice->abyKey, extra, wrq->length);
1192
1193 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
8c3337fe 1194 for (ii = 0; ii < wrq->length; ii++)
48746d7f 1195 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
48746d7f
JJ
1196
1197 if (pDevice->flags & DEVICE_FLAGS_OPENED) {
37f0777f 1198 KeybSetDefaultKey(pDevice,
48746d7f
JJ
1199 &(pDevice->sKey),
1200 dwKeyIndex | (1 << 31),
37f0777f 1201 wrq->length, NULL,
48746d7f 1202 pDevice->abyKey,
9a671f88 1203 KEY_CTL_WEP);
48746d7f 1204 }
b902fbfe 1205 pDevice->byKeyIndex = (u8)dwKeyIndex;
48746d7f 1206 pDevice->uKeyLength = wrq->length;
4e9b5e2b
AM
1207 pDevice->bTransmitKey = true;
1208 pDevice->bEncryptionEnable = true;
48746d7f 1209 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
92b96797 1210
5a673637 1211 // Do we want to just set the transmit key index?
8c3337fe 1212 if (index < 4) {
48746d7f 1213 pDevice->byKeyIndex = index;
2e9ab1e7 1214 } else if (!(wrq->flags & IW_ENCODE_MODE)) {
48746d7f
JJ
1215 rc = -EINVAL;
1216 return rc;
1217 }
92b96797
FB
1218 }
1219 // Read the flags
8c3337fe 1220 if (wrq->flags & IW_ENCODE_DISABLED) {
48746d7f 1221 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
e269fc2d
AM
1222 pMgmt->bShareKeyAlgorithm = false;
1223 pDevice->bEncryptionEnable = false;
48746d7f
JJ
1224 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1225 if (pDevice->flags & DEVICE_FLAGS_OPENED) {
48746d7f
JJ
1226 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
1227 MACvDisableKeyEntry(pDevice, uu);
48746d7f 1228 }
92b96797 1229 }
f269d1c2 1230 if (wrq->flags & IW_ENCODE_RESTRICTED) {
48746d7f 1231 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
4e9b5e2b 1232 pMgmt->bShareKeyAlgorithm = true;
92b96797 1233 }
f269d1c2 1234 if (wrq->flags & IW_ENCODE_OPEN) {
48746d7f 1235 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
e269fc2d 1236 pMgmt->bShareKeyAlgorithm = false;
92b96797
FB
1237 }
1238
37f0777f 1239 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
f1426fd7 1240
92b96797
FB
1241 return rc;
1242}
1243
921cd68b 1244int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
5743fc81 1245 union iwreq_data *wrqu, char *extra)
92b96797 1246{
da033bfd
MP
1247 struct vnt_private *pDevice = netdev_priv(dev);
1248 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1249 struct iw_point *wrq = &wrqu->encoding;
92b96797
FB
1250 char abyKey[WLAN_WEP232_KEYLEN];
1251
c91a8d5a
JJ
1252 unsigned index = (unsigned)(wrq->flags & IW_ENCODE_INDEX);
1253 PSKeyItem pKey = NULL;
92b96797
FB
1254
1255 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
1256
5743fc81
MP
1257 if (pMgmt == NULL)
1258 return -EFAULT;
1259
8c3337fe 1260 if (index > WLAN_WEP_NKEYS)
92b96797 1261 return -EINVAL;
37f0777f 1262 if (index < 1) { // get default key
8c3337fe 1263 if (pDevice->byKeyIndex < WLAN_WEP_NKEYS)
37f0777f 1264 index = pDevice->byKeyIndex;
c744fd5f 1265 else
37f0777f 1266 index = 0;
8c3337fe 1267 } else {
48746d7f 1268 index--;
8c3337fe 1269 }
92b96797
FB
1270
1271 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1272 // Check encryption mode
1273 wrq->flags = IW_ENCODE_NOKEY;
1274 // Is WEP enabled ???
1275 if (pDevice->bEncryptionEnable)
37f0777f 1276 wrq->flags |= IW_ENCODE_ENABLED;
92b96797 1277 else
37f0777f 1278 wrq->flags |= IW_ENCODE_DISABLED;
92b96797
FB
1279
1280 if (pMgmt->bShareKeyAlgorithm)
37f0777f 1281 wrq->flags |= IW_ENCODE_RESTRICTED;
92b96797 1282 else
37f0777f
JJ
1283 wrq->flags |= IW_ENCODE_OPEN;
1284 wrq->length = 0;
92b96797 1285
37f0777f 1286 if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled ||
0c5c7901 1287 pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) { // get wpa pairwise key
37f0777f 1288 if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) {
92b96797 1289 wrq->length = pKey->uKeyLength;
48746d7f
JJ
1290 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
1291 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
1292 }
b902fbfe 1293 } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (u8)index, &pKey)) {
48746d7f 1294 wrq->length = pKey->uKeyLength;
37f0777f
JJ
1295 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
1296 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
92b96797
FB
1297 }
1298
37f0777f 1299 wrq->flags |= index + 1;
92b96797
FB
1300 return 0;
1301}
1302
92b96797 1303/*
5a673637 1304 * Wireless Handler: set power mode
92b96797 1305 */
921cd68b 1306int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
5743fc81 1307 union iwreq_data *wrqu, char *extra)
92b96797 1308{
da033bfd
MP
1309 struct vnt_private *pDevice = netdev_priv(dev);
1310 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1311 struct iw_param *wrq = &wrqu->power;
48746d7f 1312 int rc = 0;
92b96797 1313
5743fc81
MP
1314 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n");
1315
1316 if (pMgmt == NULL)
1317 return -EFAULT;
92b96797 1318
48746d7f
JJ
1319 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1320 rc = -EINVAL;
1321 return rc;
92b96797
FB
1322 }
1323
1324 if (wrq->disabled) {
1325 pDevice->ePSMode = WMAC_POWER_CAM;
1326 PSvDisablePowerSaving(pDevice);
1327 return rc;
1328 }
1329 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
48746d7f 1330 pDevice->ePSMode = WMAC_POWER_FAST;
bd4208e9 1331 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
92b96797
FB
1332
1333 } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
48746d7f 1334 pDevice->ePSMode = WMAC_POWER_FAST;
bd4208e9 1335 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
92b96797 1336 }
91ec61f8 1337
92b96797
FB
1338 switch (wrq->flags & IW_POWER_MODE) {
1339 case IW_POWER_UNICAST_R:
c744fd5f 1340 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n");
92b96797
FB
1341 rc = -EINVAL;
1342 break;
1343 case IW_POWER_ALL_R:
c744fd5f 1344 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n");
92b96797
FB
1345 rc = -EINVAL;
1346 case IW_POWER_ON:
c744fd5f 1347 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n");
92b96797
FB
1348 break;
1349 default:
1350 rc = -EINVAL;
1351 }
1352
1353 return rc;
1354}
1355
1356/*
5a673637 1357 * Wireless Handler: get power mode
92b96797 1358 */
921cd68b 1359int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
5743fc81 1360 union iwreq_data *wrqu, char *extra)
92b96797 1361{
da033bfd
MP
1362 struct vnt_private *pDevice = netdev_priv(dev);
1363 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1364 struct iw_param *wrq = &wrqu->power;
48746d7f 1365 int mode = pDevice->ePSMode;
92b96797 1366
5743fc81
MP
1367 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
1368
1369 if (pMgmt == NULL)
1370 return -EFAULT;
92b96797 1371
9eac685d
CP
1372 wrq->disabled = (mode == WMAC_POWER_CAM);
1373 if (wrq->disabled)
48746d7f 1374 return 0;
92b96797
FB
1375
1376 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
dfc935ac
MP
1377 wrq->value = (int)((pMgmt->wListenInterval *
1378 pMgmt->wCurrBeaconPeriod) / 100);
92b96797
FB
1379 wrq->flags = IW_POWER_TIMEOUT;
1380 } else {
dfc935ac
MP
1381 wrq->value = (int)((pMgmt->wListenInterval *
1382 pMgmt->wCurrBeaconPeriod) / 100);
92b96797
FB
1383 wrq->flags = IW_POWER_PERIOD;
1384 }
dfc935ac 1385
92b96797 1386 wrq->flags |= IW_POWER_ALL_R;
92b96797
FB
1387 return 0;
1388}
1389
92b96797 1390/*
5a673637 1391 * Wireless Handler: get Sensitivity
92b96797 1392 */
921cd68b 1393int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
5743fc81 1394 union iwreq_data *wrqu, char *extra)
92b96797 1395{
da033bfd 1396 struct vnt_private *pDevice = netdev_priv(dev);
5743fc81 1397 struct iw_param *wrq = &wrqu->sens;
48746d7f 1398 long ldBm;
92b96797 1399
5743fc81 1400 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
4e9b5e2b 1401 if (pDevice->bLinkPass == true) {
21bba58a 1402 vnt_rf_rssi_to_dbm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
48746d7f 1403 wrq->value = ldBm;
8c3337fe 1404 } else {
48746d7f 1405 wrq->value = 0;
bb6ec004 1406 }
92b96797
FB
1407 wrq->disabled = (wrq->value == 0);
1408 wrq->fixed = 1;
92b96797
FB
1409 return 0;
1410}
1411
921cd68b 1412int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
5743fc81 1413 union iwreq_data *wrqu, char *extra)
92b96797 1414{
da033bfd
MP
1415 struct vnt_private *pDevice = netdev_priv(dev);
1416 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1417 struct iw_param *wrq = &wrqu->param;
c91a8d5a 1418 int ret = 0;
5a673637 1419 static int wpa_version = 0; // must be static to save the last value, einsn liu
c91a8d5a 1420 static int pairwise = 0;
92b96797 1421
5743fc81
MP
1422 if (pMgmt == NULL)
1423 return -EFAULT;
1424
1425 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
92b96797
FB
1426 switch (wrq->flags & IW_AUTH_INDEX) {
1427 case IW_AUTH_WPA_VERSION:
1428 wpa_version = wrq->value;
f269d1c2 1429 if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
48746d7f 1430 PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
8c3337fe 1431 } else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) {
48746d7f 1432 PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
8c3337fe 1433 } else {
48746d7f 1434 PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
92b96797 1435 }
92b96797
FB
1436 break;
1437 case IW_AUTH_CIPHER_PAIRWISE:
1438 pairwise = wrq->value;
37f0777f 1439 PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
a96f5ba6 1440 if (pairwise == IW_AUTH_CIPHER_CCMP) {
92b96797 1441 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
8c3337fe 1442 } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
92b96797 1443 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
bd2bc4c7 1444 } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
48746d7f 1445 pairwise == IW_AUTH_CIPHER_WEP104) {
92b96797 1446 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
8c3337fe 1447 } else if (pairwise == IW_AUTH_CIPHER_NONE) {
5a673637 1448 // do nothing, einsn liu
8c3337fe
JJ
1449 } else {
1450 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1451 }
92b96797
FB
1452 break;
1453 case IW_AUTH_CIPHER_GROUP:
37f0777f 1454 PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value);
f269d1c2 1455 if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
92b96797 1456 break;
8c3337fe 1457 if (pairwise == IW_AUTH_CIPHER_NONE) {
0c5c7901 1458 if (wrq->value == IW_AUTH_CIPHER_CCMP)
92b96797 1459 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
0c5c7901 1460 else
92b96797 1461 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
92b96797
FB
1462 }
1463 break;
1464 case IW_AUTH_KEY_MGMT:
a96f5ba6
NH
1465 PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version, wrq->value);
1466 if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) {
f269d1c2 1467 if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
92b96797
FB
1468 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
1469 else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
37f0777f 1470 } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
a96f5ba6 1471 if (wrq->value == 0) {
92b96797 1472 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
8c3337fe 1473 } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
92b96797 1474 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
8c3337fe
JJ
1475 } else {
1476 pMgmt->eAuthenMode = WMAC_AUTH_WPA;
92b96797 1477 }
92b96797
FB
1478 break;
1479 case IW_AUTH_TKIP_COUNTERMEASURES:
5a673637 1480 break; /* FIXME */
92b96797
FB
1481 case IW_AUTH_DROP_UNENCRYPTED:
1482 break;
1483 case IW_AUTH_80211_AUTH_ALG:
37f0777f 1484 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value);
8c3337fe 1485 if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM)
e269fc2d 1486 pMgmt->bShareKeyAlgorithm = false;
8c3337fe 1487 else if (wrq->value == IW_AUTH_ALG_SHARED_KEY)
4e9b5e2b 1488 pMgmt->bShareKeyAlgorithm = true;
92b96797
FB
1489 break;
1490 case IW_AUTH_WPA_ENABLED:
92b96797
FB
1491 break;
1492 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1493 break;
1494 case IW_AUTH_ROAMING_CONTROL:
1495 ret = -EOPNOTSUPP;
1496 break;
1497 case IW_AUTH_PRIVACY_INVOKED:
1498 pDevice->bEncryptionEnable = !!wrq->value;
e269fc2d 1499 if (pDevice->bEncryptionEnable == false) {
92b96797
FB
1500 wpa_version = 0;
1501 pairwise = 0;
1502 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
e269fc2d 1503 pMgmt->bShareKeyAlgorithm = false;
92b96797 1504 pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
48746d7f 1505 PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
92b96797 1506 }
92b96797
FB
1507 break;
1508 default:
5743fc81 1509 PRINT_K("iwctl_siwauth: not supported %x\n", wrq->flags);
92b96797
FB
1510 ret = -EOPNOTSUPP;
1511 break;
1512 }
48746d7f 1513 return ret;
92b96797
FB
1514}
1515
921cd68b 1516int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
5743fc81 1517 union iwreq_data *wrqu, char *extra)
92b96797
FB
1518{
1519 return -EOPNOTSUPP;
1520}
1521
921cd68b 1522int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
5743fc81 1523 union iwreq_data *wrqu, char *extra)
92b96797 1524{
da033bfd
MP
1525 struct vnt_private *pDevice = netdev_priv(dev);
1526 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1527 struct iw_point *wrq = &wrqu->data;
c91a8d5a 1528 int ret = 0;
92b96797 1529
5743fc81
MP
1530 if (pMgmt == NULL)
1531 return -EFAULT;
1532
a96f5ba6 1533 if (wrq->length) {
37f0777f 1534 if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
92b96797
FB
1535 ret = -EINVAL;
1536 goto out;
1537 }
a96f5ba6 1538 if (wrq->length > MAX_WPA_IE_LEN) {
92b96797
FB
1539 ret = -ENOMEM;
1540 goto out;
1541 }
1542 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
9010a286
MP
1543
1544 memcpy(pMgmt->abyWPAIE, extra, wrq->length);
92b96797 1545 pMgmt->wWPAIELen = wrq->length;
0c5c7901 1546 } else {
92b96797
FB
1547 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
1548 pMgmt->wWPAIELen = 0;
1549 }
1550
5a673637 1551out: // not completely ...not necessary in wpa_supplicant 0.5.8
4d9db977 1552 return ret;
92b96797
FB
1553}
1554
921cd68b 1555int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
5743fc81 1556 union iwreq_data *wrqu, char *extra)
92b96797 1557{
da033bfd
MP
1558 struct vnt_private *pDevice = netdev_priv(dev);
1559 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1560 struct iw_point *wrq = &wrqu->data;
c91a8d5a 1561 int ret = 0;
92b96797
FB
1562 int space = wrq->length;
1563
5743fc81
MP
1564 if (pMgmt == NULL)
1565 return -EFAULT;
1566
92b96797 1567 wrq->length = 0;
8c3337fe 1568 if (pMgmt->wWPAIELen > 0) {
92b96797 1569 wrq->length = pMgmt->wWPAIELen;
c1cd1497
MP
1570
1571 if (pMgmt->wWPAIELen <= space)
1572 memcpy(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
1573 else
92b96797
FB
1574 ret = -E2BIG;
1575 }
92b96797
FB
1576 return ret;
1577}
1578
921cd68b 1579int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
5743fc81 1580 union iwreq_data *wrqu, char *extra)
92b96797 1581{
da033bfd
MP
1582 struct vnt_private *pDevice = netdev_priv(dev);
1583 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
5743fc81 1584 struct iw_point *wrq = &wrqu->encoding;
92b96797 1585 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
a96f5ba6 1586 struct viawget_wpa_param *param = NULL;
5a673637 1587// original member
48746d7f 1588 wpa_alg alg_name;
c91a8d5a
JJ
1589 u8 addr[6];
1590 int key_idx;
37f0777f 1591 int set_tx = 0;
c91a8d5a 1592 u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
48746d7f 1593 u8 key[64];
c91a8d5a
JJ
1594 size_t seq_len = 0;
1595 size_t key_len = 0;
48746d7f 1596 u8 *buf;
48746d7f 1597 u8 key_array[64];
c91a8d5a 1598 int ret = 0;
48746d7f 1599
04212268 1600 PRINT_K("SIOCSIWENCODEEXT......\n");
48746d7f 1601
5743fc81
MP
1602 if (pMgmt == NULL)
1603 return -EFAULT;
1604
5e8c3d3e
MP
1605 if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
1606 return -ENODEV;
1607
04212268 1608 buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
48746d7f
JJ
1609 if (buf == NULL)
1610 return -ENOMEM;
04212268 1611
bd4208e9 1612 param = (struct viawget_wpa_param *)buf;
92b96797 1613
5a673637 1614// recover alg_name
48746d7f
JJ
1615 switch (ext->alg) {
1616 case IW_ENCODE_ALG_NONE:
1617 alg_name = WPA_ALG_NONE;
92b96797 1618 break;
48746d7f
JJ
1619 case IW_ENCODE_ALG_WEP:
1620 alg_name = WPA_ALG_WEP;
92b96797 1621 break;
48746d7f
JJ
1622 case IW_ENCODE_ALG_TKIP:
1623 alg_name = WPA_ALG_TKIP;
92b96797 1624 break;
48746d7f
JJ
1625 case IW_ENCODE_ALG_CCMP:
1626 alg_name = WPA_ALG_CCMP;
92b96797 1627 break;
48746d7f 1628 default:
a96f5ba6
NH
1629 PRINT_K("Unknown alg = %d\n", ext->alg);
1630 ret = -ENOMEM;
92b96797 1631 goto error;
48746d7f 1632 }
5a673637 1633// recover addr
48746d7f 1634 memcpy(addr, ext->addr.sa_data, ETH_ALEN);
5a673637 1635// recover key_idx
48746d7f 1636 key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
5a673637 1637// recover set_tx
f269d1c2 1638 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
48746d7f 1639 set_tx = 1;
5a673637 1640// recover seq,seq_len
f269d1c2 1641 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
a96f5ba6 1642 seq_len = IW_ENCODE_SEQ_MAX_SIZE;
48746d7f 1643 memcpy(seq, ext->rx_seq, seq_len);
92b96797 1644 }
5a673637 1645// recover key,key_len
f269d1c2 1646 if (ext->key_len) {
37f0777f 1647 key_len = ext->key_len;
48746d7f 1648 memcpy(key, &ext->key[0], key_len);
92b96797 1649 }
48746d7f 1650 memset(key_array, 0, 64);
37f0777f 1651 if (key_len > 0) {
48746d7f
JJ
1652 memcpy(key_array, key, key_len);
1653 if (key_len == 32) {
1654 // notice ! the oder
1655 memcpy(&key_array[16], &key[24], 8);
1656 memcpy(&key_array[24], &key[16], 8);
1657 }
92b96797
FB
1658 }
1659
1660/**************Translate iw_encode_ext to viawget_wpa_param****************/
48746d7f
JJ
1661 memcpy(param->addr, addr, ETH_ALEN);
1662 param->u.wpa_key.alg_name = (int)alg_name;
1663 param->u.wpa_key.set_tx = set_tx;
1664 param->u.wpa_key.key_index = key_idx;
1665 param->u.wpa_key.key_len = key_len;
1666 param->u.wpa_key.key = (u8 *)key_array;
1667 param->u.wpa_key.seq = (u8 *)seq;
1668 param->u.wpa_key.seq_len = seq_len;
92b96797 1669
5a673637
JJ
1670/****set if current action is Network Manager count?? */
1671/****this method is so foolish,but there is no other way??? */
f269d1c2 1672 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
a96f5ba6 1673 if (param->u.wpa_key.key_index == 0) {
4e9b5e2b 1674 pDevice->bwextstep0 = true;
48746d7f 1675 }
4e9b5e2b 1676 if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
e269fc2d 1677 pDevice->bwextstep0 = false;
4e9b5e2b 1678 pDevice->bwextstep1 = true;
48746d7f 1679 }
4e9b5e2b 1680 if ((pDevice->bwextstep1 == true) && (param->u.wpa_key.key_index == 2)) {
e269fc2d 1681 pDevice->bwextstep1 = false;
4e9b5e2b 1682 pDevice->bwextstep2 = true;
48746d7f 1683 }
4e9b5e2b 1684 if ((pDevice->bwextstep2 == true) && (param->u.wpa_key.key_index == 3)) {
e269fc2d 1685 pDevice->bwextstep2 = false;
4e9b5e2b 1686 pDevice->bwextstep3 = true;
48746d7f
JJ
1687 }
1688 }
4e9b5e2b 1689 if (pDevice->bwextstep3 == true) {
48746d7f 1690 PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
e269fc2d
AM
1691 pDevice->bwextstep0 = false;
1692 pDevice->bwextstep1 = false;
1693 pDevice->bwextstep2 = false;
1694 pDevice->bwextstep3 = false;
4e9b5e2b 1695 pDevice->bWPASuppWextEnabled = true;
37f0777f
JJ
1696 memset(pMgmt->abyDesireBSSID, 0xFF, 6);
1697 KeyvInitTable(pDevice, &pDevice->sKey);
92b96797 1698 }
5a673637 1699/*******/
c9f3bc59 1700 ret = wpa_set_keys(pDevice, param);
92b96797
FB
1701
1702error:
04212268 1703 kfree(buf);
92b96797
FB
1704 return ret;
1705}
1706
921cd68b 1707int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
5743fc81 1708 union iwreq_data *wrqu, char *extra)
92b96797 1709{
48746d7f 1710 return -EOPNOTSUPP;
92b96797
FB
1711}
1712
921cd68b 1713int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
5743fc81 1714 union iwreq_data *wrqu, char *extra)
92b96797 1715{
da033bfd
MP
1716 struct vnt_private *pDevice = netdev_priv(dev);
1717 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
92b96797 1718 struct iw_mlme *mlme = (struct iw_mlme *)extra;
92b96797
FB
1719 int ret = 0;
1720
5743fc81
MP
1721 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
1722
1723 if (pMgmt == NULL)
1724 return -EFAULT;
1725
8c3337fe 1726 if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
92b96797
FB
1727 ret = -EINVAL;
1728 return ret;
1729 }
a96f5ba6 1730 switch (mlme->cmd) {
92b96797 1731 case IW_MLME_DEAUTH:
92b96797 1732 case IW_MLME_DISASSOC:
4e9b5e2b 1733 if (pDevice->bLinkPass == true) {
48746d7f 1734 PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
4063d060 1735 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE,
48746d7f 1736 NULL);
92b96797
FB
1737 }
1738 break;
1739 default:
1740 ret = -EOPNOTSUPP;
1741 }
92b96797 1742 return ret;
92b96797
FB
1743}
1744
5743fc81
MP
1745static int iwctl_config_commit(struct net_device *dev,
1746 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1747{
1748 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SIOCSIWCOMMIT\n");
1749
1750 return 0;
1751}
1752
c91a8d5a 1753static const iw_handler iwctl_handler[] = {
5743fc81
MP
1754 IW_HANDLER(SIOCSIWCOMMIT, iwctl_config_commit),
1755 IW_HANDLER(SIOCGIWNAME, iwctl_giwname),
1756 IW_HANDLER(SIOCSIWFREQ, iwctl_siwfreq),
1757 IW_HANDLER(SIOCGIWFREQ, iwctl_giwfreq),
1758 IW_HANDLER(SIOCSIWMODE, iwctl_siwmode),
1759 IW_HANDLER(SIOCGIWMODE, iwctl_giwmode),
1760 IW_HANDLER(SIOCGIWSENS, iwctl_giwsens),
1761 IW_HANDLER(SIOCGIWRANGE, iwctl_giwrange),
1762 IW_HANDLER(SIOCSIWAP, iwctl_siwap),
1763 IW_HANDLER(SIOCGIWAP, iwctl_giwap),
1764 IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
1765 IW_HANDLER(SIOCGIWAPLIST, iwctl_giwaplist),
1766 IW_HANDLER(SIOCSIWSCAN, iwctl_siwscan),
1767 IW_HANDLER(SIOCGIWSCAN, iwctl_giwscan),
1768 IW_HANDLER(SIOCSIWESSID, iwctl_siwessid),
1769 IW_HANDLER(SIOCGIWESSID, iwctl_giwessid),
1770 IW_HANDLER(SIOCSIWRATE, iwctl_siwrate),
1771 IW_HANDLER(SIOCGIWRATE, iwctl_giwrate),
1772 IW_HANDLER(SIOCSIWRTS, iwctl_siwrts),
1773 IW_HANDLER(SIOCGIWRTS, iwctl_giwrts),
1774 IW_HANDLER(SIOCSIWFRAG, iwctl_siwfrag),
1775 IW_HANDLER(SIOCGIWFRAG, iwctl_giwfrag),
1776 IW_HANDLER(SIOCSIWRETRY, iwctl_siwretry),
1777 IW_HANDLER(SIOCGIWRETRY, iwctl_giwretry),
1778 IW_HANDLER(SIOCSIWENCODE, iwctl_siwencode),
1779 IW_HANDLER(SIOCGIWENCODE, iwctl_giwencode),
1780 IW_HANDLER(SIOCSIWPOWER, iwctl_siwpower),
1781 IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
1782 IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
1783 IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
5743fc81
MP
1784 IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
1785 IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
1786 IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
1787 IW_HANDLER(SIOCGIWENCODEEXT, iwctl_giwencodeext)
92b96797
FB
1788};
1789
c91a8d5a 1790static const iw_handler iwctl_private_handler[] = {
5a673637 1791 NULL, // SIOCIWFIRSTPRIV
92b96797
FB
1792};
1793
c91a8d5a 1794const struct iw_handler_def iwctl_handler_def = {
37f0777f 1795 .get_wireless_stats = &iwctl_get_wireless_stats,
5743fc81 1796 .num_standard = ARRAY_SIZE(iwctl_handler),
37f0777f
JJ
1797 .num_private = 0,
1798 .num_private_args = 0,
5743fc81 1799 .standard = iwctl_handler,
37f0777f
JJ
1800 .private = NULL,
1801 .private_args = NULL,
92b96797 1802};
This page took 0.657672 seconds and 5 git commands to generate.