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 * 20 * File: wpactl.c 21 * 22 * Purpose: handle wpa supplicant ioctl input/out functions 23 * 24 * Author: Lyndon Chen 25 * 26 * Date: July 28, 2006 27 * 28 * Functions: 29 * 30 * Revision History: 31 * 32 */ 33 34#include "wpactl.h" 35#include "key.h" 36#include "mac.h" 37#include "device.h" 38#include "wmgr.h" 39#include "iocmd.h" 40#include "iowpa.h" 41#include "control.h" 42#include "rndis.h" 43#include "rf.h" 44 45/*--------------------- Static Definitions -------------------------*/ 46 47#define VIAWGET_WPA_MAX_BUF_SIZE 1024 48 49 50 51static const int frequency_list[] = { 52 2412, 2417, 2422, 2427, 2432, 2437, 2442, 53 2447, 2452, 2457, 2462, 2467, 2472, 2484 54}; 55/*--------------------- Static Classes ----------------------------*/ 56 57/*--------------------- Static Variables --------------------------*/ 58//static int msglevel =MSG_LEVEL_DEBUG; 59static int msglevel =MSG_LEVEL_INFO; 60 61/*--------------------- Static Functions --------------------------*/ 62 63 64 65 66/*--------------------- Export Variables --------------------------*/ 67static void wpadev_setup(struct net_device *dev) 68{ 69 dev->type = ARPHRD_IEEE80211; 70 dev->hard_header_len = ETH_HLEN; 71 dev->mtu = 2048; 72 dev->addr_len = ETH_ALEN; 73 dev->tx_queue_len = 1000; 74 75 memset(dev->broadcast,0xFF, ETH_ALEN); 76 77 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 78} 79 80/* 81 * Description: 82 * register netdev for wpa supplicant deamon 83 * 84 * Parameters: 85 * In: 86 * pDevice - 87 * enable - 88 * Out: 89 * 90 * Return Value: 91 * 92 */ 93 94static int wpa_init_wpadev(PSDevice pDevice) 95{ 96 PSDevice wpadev_priv; 97 struct net_device *dev = pDevice->dev; 98 int ret=0; 99 100 pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup); 101 if (pDevice->wpadev == NULL) 102 return -ENOMEM; 103 104 wpadev_priv = netdev_priv(pDevice->wpadev); 105 *wpadev_priv = *pDevice; 106 memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN); 107 pDevice->wpadev->base_addr = dev->base_addr; 108 pDevice->wpadev->irq = dev->irq; 109 pDevice->wpadev->mem_start = dev->mem_start; 110 pDevice->wpadev->mem_end = dev->mem_end; 111 ret = register_netdev(pDevice->wpadev); 112 if (ret) { 113 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n", 114 dev->name); 115 free_netdev(pDevice->wpadev); 116 return -1; 117 } 118 119 if (pDevice->skb == NULL) { 120 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); 121 if (pDevice->skb == NULL) 122 return -ENOMEM; 123 } 124 125 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n", 126 dev->name, pDevice->wpadev->name); 127 128 return 0; 129} 130 131 132/* 133 * Description: 134 * unregister net_device (wpadev) 135 * 136 * Parameters: 137 * In: 138 * pDevice - 139 * Out: 140 * 141 * Return Value: 142 * 143 */ 144 145static int wpa_release_wpadev(PSDevice pDevice) 146{ 147 if (pDevice->skb) { 148 dev_kfree_skb(pDevice->skb); 149 pDevice->skb = NULL; 150 } 151 152 if (pDevice->wpadev) { 153 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", 154 pDevice->dev->name, pDevice->wpadev->name); 155 unregister_netdev(pDevice->wpadev); 156 free_netdev(pDevice->wpadev); 157 pDevice->wpadev = NULL; 158 } 159 160 return 0; 161} 162 163 164 165 166 167/* 168 * Description: 169 * Set enable/disable dev for wpa supplicant deamon 170 * 171 * Parameters: 172 * In: 173 * pDevice - 174 * val - 175 * Out: 176 * 177 * Return Value: 178 * 179 */ 180 181int wpa_set_wpadev(PSDevice pDevice, int val) 182{ 183 if (val) 184 return wpa_init_wpadev(pDevice); 185 else 186 return wpa_release_wpadev(pDevice); 187} 188 189/* 190 * Description: 191 * Set WPA algorithm & keys 192 * 193 * Parameters: 194 * In: 195 * pDevice - 196 * param - 197 * Out: 198 * 199 * Return Value: 200 * 201 */ 202 203 int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL fcpfkernel) 204{ 205 struct viawget_wpa_param *param=ctx; 206 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 207 DWORD dwKeyIndex = 0; 208 BYTE abyKey[MAX_KEY_LEN]; 209 BYTE abySeq[MAX_KEY_LEN]; 210 QWORD KeyRSC; 211// NDIS_802_11_KEY_RSC KeyRSC; 212 BYTE byKeyDecMode = KEY_CTL_WEP; 213 int ret = 0; 214 int uu, ii; 215 216 217 if (param->u.wpa_key.alg_name > WPA_ALG_CCMP) 218 return -EINVAL; 219 220 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name); 221 if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { 222 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 223 pDevice->bEncryptionEnable = FALSE; 224 pDevice->byKeyIndex = 0; 225 pDevice->bTransmitKey = FALSE; 226 for (uu=0; uu<MAX_KEY_TABLE; uu++) { 227 MACvDisableKeyEntry(pDevice, uu); 228 } 229 return ret; 230 } 231 232 spin_unlock_irq(&pDevice->lock); 233 if(param->u.wpa_key.key && fcpfkernel) { 234 memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); 235 } 236 else { 237 if (param->u.wpa_key.key && 238 copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) { 239 spin_lock_irq(&pDevice->lock); 240 return -EINVAL; 241 } 242 } 243 spin_lock_irq(&pDevice->lock); 244 245 dwKeyIndex = (DWORD)(param->u.wpa_key.key_index); 246 247 if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { 248 if (dwKeyIndex > 3) { 249 return -EINVAL; 250 } 251 else { 252 if (param->u.wpa_key.set_tx) { 253 pDevice->byKeyIndex = (BYTE)dwKeyIndex; 254 pDevice->bTransmitKey = TRUE; 255 dwKeyIndex |= (1 << 31); 256 } 257 KeybSetDefaultKey( pDevice, 258 &(pDevice->sKey), 259 dwKeyIndex & ~(BIT30 | USE_KEYRSC), 260 param->u.wpa_key.key_len, 261 NULL, 262 abyKey, 263 KEY_CTL_WEP 264 ); 265 266 } 267 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 268 pDevice->bEncryptionEnable = TRUE; 269 return ret; 270 } 271 272 spin_unlock_irq(&pDevice->lock); 273 if(param->u.wpa_key.seq && fcpfkernel) { 274 memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); 275 } 276 else { 277 if (param->u.wpa_key.seq && 278 copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) { 279 spin_lock_irq(&pDevice->lock); 280 return -EINVAL; 281 } 282 } 283 spin_lock_irq(&pDevice->lock); 284 285 if (param->u.wpa_key.seq_len > 0) { 286 for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) { 287 if (ii < 4) 288 LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8)); 289 else 290 HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8)); 291 //KeyRSC |= (abySeq[ii] << (ii * 8)); 292 } 293 dwKeyIndex |= 1 << 29; 294 } 295 296 if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { 297 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n"); 298 return -EINVAL; 299 } 300 301 if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) { 302 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 303 } 304 305 if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) { 306 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 307 } 308 309 if (param->u.wpa_key.set_tx) 310 dwKeyIndex |= (1 << 31); 311 312 313 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) 314 byKeyDecMode = KEY_CTL_CCMP; 315 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) 316 byKeyDecMode = KEY_CTL_TKIP; 317 else 318 byKeyDecMode = KEY_CTL_WEP; 319 320 // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled 321 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { 322 if (param->u.wpa_key.key_len == MAX_KEY_LEN) 323 byKeyDecMode = KEY_CTL_TKIP; 324 else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) 325 byKeyDecMode = KEY_CTL_WEP; 326 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) 327 byKeyDecMode = KEY_CTL_WEP; 328 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { 329 if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) 330 byKeyDecMode = KEY_CTL_WEP; 331 else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) 332 byKeyDecMode = KEY_CTL_WEP; 333 } 334 335 // Check TKIP key length 336 if ((byKeyDecMode == KEY_CTL_TKIP) && 337 (param->u.wpa_key.key_len != MAX_KEY_LEN)) { 338 // TKIP Key must be 256 bits 339 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n")); 340 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); 341 return -EINVAL; 342 } 343 // Check AES key length 344 if ((byKeyDecMode == KEY_CTL_CCMP) && 345 (param->u.wpa_key.key_len != AES_KEY_LEN)) { 346 // AES Key must be 128 bits 347 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n"); 348 return -EINVAL; 349 } 350 351 if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { 352 /* if broadcast, set the key as every key entry's group key */ 353 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); 354 355 if ((KeybSetAllGroupKey(pDevice, 356 &(pDevice->sKey), 357 dwKeyIndex, 358 param->u.wpa_key.key_len, 359 (PQWORD) &(KeyRSC), 360 (PBYTE)abyKey, 361 byKeyDecMode 362 ) == TRUE) && 363 (KeybSetDefaultKey(pDevice, 364 &(pDevice->sKey), 365 dwKeyIndex, 366 param->u.wpa_key.key_len, 367 (PQWORD) &(KeyRSC), 368 (PBYTE)abyKey, 369 byKeyDecMode 370 ) == TRUE) ) { 371 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); 372 373 } else { 374 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n")); 375 return -EINVAL; 376 } 377 378 } else { 379 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n"); 380 // BSSID not 0xffffffffffff 381 // Pairwise Key can't be WEP 382 if (byKeyDecMode == KEY_CTL_WEP) { 383 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n"); 384 return -EINVAL; 385 } 386 387 dwKeyIndex |= (1 << 30); // set pairwise key 388 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { 389 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n")); 390 return -EINVAL; 391 } 392 if (KeybSetKey(pDevice, 393 &(pDevice->sKey), 394 ¶m->addr[0], 395 dwKeyIndex, 396 param->u.wpa_key.key_len, 397 (PQWORD) &(KeyRSC), 398 (PBYTE)abyKey, 399 byKeyDecMode 400 ) == TRUE) { 401 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); 402 403 } else { 404 // Key Table Full 405 if (!compare_ether_addr(¶m->addr[0], pDevice->abyBSSID)) { 406 //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n")); 407 return -EINVAL; 408 409 } else { 410 // Save Key and configure just before associate/reassociate to BSSID 411 // we do not implement now 412 return -EINVAL; 413 } 414 } 415 } // BSSID not 0xffffffffffff 416 if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { 417 pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index; 418 pDevice->bTransmitKey = TRUE; 419 } 420 pDevice->bEncryptionEnable = TRUE; 421 422/* 423 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", 424 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0], 425 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1], 426 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2], 427 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3], 428 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4] 429 ); 430*/ 431 432 return ret; 433 434} 435 436 437/* 438 * Description: 439 * enable wpa auth & mode 440 * 441 * Parameters: 442 * In: 443 * pDevice - 444 * param - 445 * Out: 446 * 447 * Return Value: 448 * 449 */ 450 451static int wpa_set_wpa(PSDevice pDevice, 452 struct viawget_wpa_param *param) 453{ 454 455 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 456 int ret = 0; 457 458 pMgmt->eAuthenMode = WMAC_AUTH_OPEN; 459 pMgmt->bShareKeyAlgorithm = FALSE; 460 461 return ret; 462} 463 464 465 466 467 /* 468 * Description: 469 * set disassociate 470 * 471 * Parameters: 472 * In: 473 * pDevice - 474 * param - 475 * Out: 476 * 477 * Return Value: 478 * 479 */ 480 481static int wpa_set_disassociate(PSDevice pDevice, 482 struct viawget_wpa_param *param) 483{ 484 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 485 int ret = 0; 486 487 spin_lock_irq(&pDevice->lock); 488 if (pDevice->bLinkPass) { 489 if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) 490 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL); 491 } 492 spin_unlock_irq(&pDevice->lock); 493 494 return ret; 495} 496 497 498 499/* 500 * Description: 501 * enable scan process 502 * 503 * Parameters: 504 * In: 505 * pDevice - 506 * param - 507 * Out: 508 * 509 * Return Value: 510 * 511 */ 512 513static int wpa_set_scan(PSDevice pDevice, 514 struct viawget_wpa_param *param) 515{ 516 int ret = 0; 517 518//2007-0919-01<Add>by MikeLiu 519/**set ap_scan=1&&scan_ssid=1 under hidden ssid mode**/ 520 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 521 PWLAN_IE_SSID pItemSSID; 522printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n", 523 param->u.scan_req.ssid,param->u.scan_req.ssid_len); 524// Set the SSID 525memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 526pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; 527pItemSSID->byElementID = WLAN_EID_SSID; 528memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len); 529pItemSSID->len = param->u.scan_req.ssid_len; 530 531 spin_lock_irq(&pDevice->lock); 532 BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); 533 /* bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); */ 534 bScheduleCommand((void *) pDevice, 535 WLAN_CMD_BSSID_SCAN, 536 pMgmt->abyDesireSSID); 537 spin_unlock_irq(&pDevice->lock); 538 539 return ret; 540} 541 542 543 544/* 545 * Description: 546 * get bssid 547 * 548 * Parameters: 549 * In: 550 * pDevice - 551 * param - 552 * Out: 553 * 554 * Return Value: 555 * 556 */ 557 558static int wpa_get_bssid(PSDevice pDevice, 559 struct viawget_wpa_param *param) 560{ 561 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 562 int ret = 0; 563 memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6); 564 565 return ret; 566 567} 568 569 570/* 571 * Description: 572 * get bssid 573 * 574 * Parameters: 575 * In: 576 * pDevice - 577 * param - 578 * Out: 579 * 580 * Return Value: 581 * 582 */ 583 584static int wpa_get_ssid(PSDevice pDevice, 585 struct viawget_wpa_param *param) 586{ 587 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 588 PWLAN_IE_SSID pItemSSID; 589 int ret = 0; 590 591 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; 592 593 memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len); 594 param->u.wpa_associate.ssid_len = pItemSSID->len; 595 596 return ret; 597} 598 599 600 601/* 602 * Description: 603 * get scan results 604 * 605 * Parameters: 606 * In: 607 * pDevice - 608 * param - 609 * Out: 610 * 611 * Return Value: 612 * 613 */ 614 615static int wpa_get_scan(PSDevice pDevice, 616 struct viawget_wpa_param *param) 617{ 618 struct viawget_scan_result *scan_buf; 619 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 620 PWLAN_IE_SSID pItemSSID; 621 PKnownBSS pBSS; 622 PBYTE pBuf; 623 int ret = 0; 624 u16 count = 0; 625 u16 ii, jj; 626 long ldBm;//James //add 627 628//******mike:bubble sort by stronger RSSI*****// 629 630 PBYTE ptempBSS; 631 632 633 634 ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC); 635 636 if (ptempBSS == NULL) { 637 638 printk("bubble sort kmalloc memory fail@@@\n"); 639 640 ret = -ENOMEM; 641 642 return ret; 643 644 } 645 646 for (ii = 0; ii < MAX_BSS_NUM; ii++) { 647 648 for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) { 649 650 if ((pMgmt->sBSSList[jj].bActive != TRUE) || 651 652 ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) { 653 654 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS)); 655 656 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS)); 657 658 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS)); 659 660 } 661 662 } 663 664 }; 665 666 kfree(ptempBSS); 667 668 // printk("bubble sort result:\n"); 669 670 count = 0; 671 pBSS = &(pMgmt->sBSSList[0]); 672 for (ii = 0; ii < MAX_BSS_NUM; ii++) { 673 pBSS = &(pMgmt->sBSSList[ii]); 674 if (!pBSS->bActive) 675 continue; 676 count++; 677 }; 678 679 pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC); 680 681 if (pBuf == NULL) { 682 ret = -ENOMEM; 683 return ret; 684 } 685 scan_buf = (struct viawget_scan_result *)pBuf; 686 pBSS = &(pMgmt->sBSSList[0]); 687 for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) { 688 pBSS = &(pMgmt->sBSSList[ii]); 689 if (pBSS->bActive) { 690 if (jj >= count) 691 break; 692 memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN); 693 pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; 694 memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len); 695 scan_buf->ssid_len = pItemSSID->len; 696 scan_buf->freq = frequency_list[pBSS->uChannel-1]; 697 scan_buf->caps = pBSS->wCapInfo; //DavidWang for sharemode 698//20080717-05,<Add> by James Li 699 RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); 700 if(-ldBm<50){ 701 scan_buf->qual = 100; 702 }else if(-ldBm > 90) { 703 scan_buf->qual = 0; 704 }else { 705 scan_buf->qual=(40-(-ldBm-50))*100/40; 706 } 707 708 //James 709 //scan_buf->caps = pBSS->wCapInfo; 710 //scan_buf->qual = 711 scan_buf->noise = 0; 712 scan_buf->level = ldBm; 713 //20080717-05,<Add> by James Li--End 714 //scan_buf->maxrate = 715 if (pBSS->wWPALen != 0) { 716 scan_buf->wpa_ie_len = pBSS->wWPALen; 717 memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen); 718 } 719 if (pBSS->wRSNLen != 0) { 720 scan_buf->rsn_ie_len = pBSS->wRSNLen; 721 memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen); 722 } 723 scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result)); 724 jj ++; 725 } 726 } 727 728 if (jj < count) 729 count = jj; 730 731 if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) { 732 ret = -EFAULT; 733 }; 734 param->u.scan_results.scan_count = count; 735 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count) 736 737 kfree(pBuf); 738 return ret; 739} 740 741 742 743/* 744 * Description: 745 * set associate with AP 746 * 747 * Parameters: 748 * In: 749 * pDevice - 750 * param - 751 * Out: 752 * 753 * Return Value: 754 * 755 */ 756 757static int wpa_set_associate(PSDevice pDevice, 758 struct viawget_wpa_param *param) 759{ 760 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 761 PWLAN_IE_SSID pItemSSID; 762 BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 763 BYTE abyWPAIE[64]; 764 int ret = 0; 765 BOOL bwepEnabled=FALSE; 766 767 // set key type & algorithm 768 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite); 769 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite); 770 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite); 771 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg); 772 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode); 773 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); 774 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm); //Davidwang 775 776 if (param->u.wpa_associate.wpa_ie && 777 copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) 778 return -EINVAL; 779 780 if (param->u.wpa_associate.mode == 1) 781 pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; 782 else 783 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; 784 785 // set bssid 786 if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) 787 memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); 788 // set ssid 789 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 790 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; 791 pItemSSID->byElementID = WLAN_EID_SSID; 792 pItemSSID->len = param->u.wpa_associate.ssid_len; 793 memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len); 794 795 if (param->u.wpa_associate.wpa_ie_len == 0) { 796 if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY) 797 pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; 798 else 799 pMgmt->eAuthenMode = WMAC_AUTH_OPEN; 800 } else if (abyWPAIE[0] == RSN_INFO_ELEM) { 801 if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) 802 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; 803 else 804 pMgmt->eAuthenMode = WMAC_AUTH_WPA2; 805 } else { 806 if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE) 807 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; 808 else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) 809 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; 810 else 811 pMgmt->eAuthenMode = WMAC_AUTH_WPA; 812 } 813 814 switch (param->u.wpa_associate.pairwise_suite) { 815 case CIPHER_CCMP: 816 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 817 break; 818 case CIPHER_TKIP: 819 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 820 break; 821 case CIPHER_WEP40: 822 case CIPHER_WEP104: 823 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 824 bwepEnabled = TRUE; 825 // printk("****************wpa_set_associate:set CIPHER_WEP40_104\n"); 826 break; 827 case CIPHER_NONE: 828 if (param->u.wpa_associate.group_suite == CIPHER_CCMP) 829 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 830 else 831 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 832 break; 833 default: 834 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 835 }; 836 837 pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm; 838 // if ((pMgmt->Roam_dbm > 40)&&(pMgmt->Roam_dbm<80)) 839 // pDevice->bEnableRoaming = TRUE; 840 841 if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { //@wep-sharekey 842 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 843 pMgmt->bShareKeyAlgorithm = TRUE; 844 } 845 else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { 846 if(bwepEnabled==TRUE) { //@open-wep 847 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 848 } 849 else { //@only open 850 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 851 } 852 } 853//mike save old encryption status 854 pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus; 855 856 if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled) 857 pDevice->bEncryptionEnable = TRUE; 858 else 859 pDevice->bEncryptionEnable = FALSE; 860 861 if ((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || 862 ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bwepEnabled==TRUE))) { 863 //mike re-comment:open-wep && sharekey-wep needn't do initial key!! 864 865 } 866 else 867 KeyvInitTable(pDevice,&pDevice->sKey); 868 869 spin_lock_irq(&pDevice->lock); 870 pDevice->bLinkPass = FALSE; 871 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); 872 memset(pMgmt->abyCurrBSSID, 0, 6); 873 pMgmt->eCurrState = WMAC_STATE_IDLE; 874 netif_stop_queue(pDevice->dev); 875 876//20080701-02,<Add> by Mike Liu 877/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/ 878{ 879 PKnownBSS pCurr = NULL; 880 pCurr = BSSpSearchBSSList(pDevice, 881 pMgmt->abyDesireBSSID, 882 pMgmt->abyDesireSSID, 883 pDevice->eConfigPHYMode 884 ); 885 886 if (pCurr == NULL){ 887 printk("wpa_set_associate---->hidden mode site survey before associate.......\n"); 888 bScheduleCommand((void *) pDevice, 889 WLAN_CMD_BSSID_SCAN, 890 pMgmt->abyDesireSSID); 891 }; 892} 893/****************************************************************/ 894 895 bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); 896 spin_unlock_irq(&pDevice->lock); 897 898 return ret; 899} 900 901 902/* 903 * Description: 904 * wpa_ioctl main function supported for wpa supplicant 905 * 906 * Parameters: 907 * In: 908 * pDevice - 909 * iw_point - 910 * Out: 911 * 912 * Return Value: 913 * 914 */ 915 916int wpa_ioctl(PSDevice pDevice, struct iw_point *p) 917{ 918 struct viawget_wpa_param *param; 919 int ret = 0; 920 int wpa_ioctl = 0; 921 922 if (p->length < sizeof(struct viawget_wpa_param) || 923 p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) 924 return -EINVAL; 925 926 param = kmalloc((int)p->length, (int)GFP_KERNEL); 927 if (param == NULL) 928 return -ENOMEM; 929 930 if (copy_from_user(param, p->pointer, p->length)) { 931 ret = -EFAULT; 932 goto out; 933 } 934 935 switch (param->cmd) { 936 case VIAWGET_SET_WPA: 937 ret = wpa_set_wpa(pDevice, param); 938 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n"); 939 break; 940 941 case VIAWGET_SET_KEY: 942 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n"); 943 spin_lock_irq(&pDevice->lock); 944 ret = wpa_set_keys(pDevice, param, FALSE); 945 spin_unlock_irq(&pDevice->lock); 946 break; 947 948 case VIAWGET_SET_SCAN: 949 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n"); 950 ret = wpa_set_scan(pDevice, param); 951 break; 952 953 case VIAWGET_GET_SCAN: 954 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n"); 955 ret = wpa_get_scan(pDevice, param); 956 wpa_ioctl = 1; 957 break; 958 959 case VIAWGET_GET_SSID: 960 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n"); 961 ret = wpa_get_ssid(pDevice, param); 962 wpa_ioctl = 1; 963 break; 964 965 case VIAWGET_GET_BSSID: 966 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n"); 967 ret = wpa_get_bssid(pDevice, param); 968 wpa_ioctl = 1; 969 break; 970 971 case VIAWGET_SET_ASSOCIATE: 972 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n"); 973 ret = wpa_set_associate(pDevice, param); 974 break; 975 976 case VIAWGET_SET_DISASSOCIATE: 977 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n"); 978 ret = wpa_set_disassociate(pDevice, param); 979 break; 980 981 case VIAWGET_SET_DROP_UNENCRYPT: 982 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n"); 983 break; 984 985 case VIAWGET_SET_DEAUTHENTICATE: 986 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n"); 987 break; 988 989 default: 990 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n", 991 param->cmd); 992 return -EOPNOTSUPP; 993 break; 994 } 995 996 if ((ret == 0) && wpa_ioctl) { 997 if (copy_to_user(p->pointer, param, p->length)) { 998 ret = -EFAULT; 999 goto out; 1000 } 1001 } 1002 1003out: 1004 if (param != NULL) 1005 kfree(param); 1006 1007 return ret; 1008} 1009