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