Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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