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