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: hostap.c 20 * 21 * Purpose: handle hostap deamon ioctl input/out functions 22 * 23 * Author: Lyndon Chen 24 * 25 * Date: Oct. 20, 2003 26 * 27 * Functions: 28 * 29 * Revision History: 30 * 31 */ 32 33#include "hostap.h" 34#include "iocmd.h" 35#include "mac.h" 36#include "card.h" 37#include "baseband.h" 38#include "wpactl.h" 39#include "key.h" 40#include "datarate.h" 41 42#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024 43#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0 44#define HOSTAP_CRYPT_FLAG_PERMANENT BIT1 45#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2 46#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 47#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4 48#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 49#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6 50#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7 51 52 53/*--------------------- Static Definitions -------------------------*/ 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 --------------------------*/ 67 68 69/* 70 * Description: 71 * register net_device (AP) for hostap deamon 72 * 73 * Parameters: 74 * In: 75 * pDevice - 76 * rtnl_locked - 77 * Out: 78 * 79 * Return Value: 80 * 81 */ 82 83static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) 84{ 85 PSDevice apdev_priv; 86 struct net_device *dev = pDevice->dev; 87 int ret; 88 const struct net_device_ops apdev_netdev_ops = { 89 .ndo_start_xmit = pDevice->tx_80211, 90 }; 91 92 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); 93 94 pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL); 95 if (pDevice->apdev == NULL) 96 return -ENOMEM; 97 98 apdev_priv = netdev_priv(pDevice->apdev); 99 *apdev_priv = *pDevice; 100 memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN); 101 102 pDevice->apdev->netdev_ops = &apdev_netdev_ops; 103 104 pDevice->apdev->type = ARPHRD_IEEE80211; 105 106 pDevice->apdev->base_addr = dev->base_addr; 107 pDevice->apdev->irq = dev->irq; 108 pDevice->apdev->mem_start = dev->mem_start; 109 pDevice->apdev->mem_end = dev->mem_end; 110 sprintf(pDevice->apdev->name, "%sap", dev->name); 111 if (rtnl_locked) 112 ret = register_netdevice(pDevice->apdev); 113 else 114 ret = register_netdev(pDevice->apdev); 115 if (ret) { 116 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n", 117 dev->name); 118 return -1; 119 } 120 121 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n", 122 dev->name, pDevice->apdev->name); 123 124 KeyvInitTable(pDevice,&pDevice->sKey); 125 126 return 0; 127} 128 129/* 130 * Description: 131 * unregister net_device(AP) 132 * 133 * Parameters: 134 * In: 135 * pDevice - 136 * rtnl_locked - 137 * Out: 138 * 139 * Return Value: 140 * 141 */ 142 143static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) 144{ 145 146 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name); 147 148 if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) { 149 if (rtnl_locked) 150 unregister_netdevice(pDevice->apdev); 151 else 152 unregister_netdev(pDevice->apdev); 153 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", 154 pDevice->dev->name, pDevice->apdev->name); 155 } 156 kfree(pDevice->apdev); 157 pDevice->apdev = NULL; 158 pDevice->bEnable8021x = FALSE; 159 pDevice->bEnableHostWEP = FALSE; 160 pDevice->bEncryptionEnable = FALSE; 161 162 return 0; 163} 164 165 166/* 167 * Description: 168 * Set enable/disable hostapd mode 169 * 170 * Parameters: 171 * In: 172 * pDevice - 173 * rtnl_locked - 174 * Out: 175 * 176 * Return Value: 177 * 178 */ 179 180int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) 181{ 182 if (val < 0 || val > 1) 183 return -EINVAL; 184 185 if (pDevice->bEnableHostapd == val) 186 return 0; 187 188 pDevice->bEnableHostapd = val; 189 190 if (val) 191 return hostap_enable_hostapd(pDevice, rtnl_locked); 192 else 193 return hostap_disable_hostapd(pDevice, rtnl_locked); 194} 195 196 197/* 198 * Description: 199 * remove station function supported for hostap deamon 200 * 201 * Parameters: 202 * In: 203 * pDevice - 204 * param - 205 * Out: 206 * 207 * Return Value: 208 * 209 */ 210static int hostap_remove_sta(PSDevice pDevice, 211 struct viawget_hostapd_param *param) 212{ 213 unsigned int uNodeIndex; 214 215 216 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { 217 BSSvRemoveOneNode(pDevice, uNodeIndex); 218 } 219 else { 220 return -ENOENT; 221 } 222 return 0; 223} 224 225/* 226 * Description: 227 * add a station from hostap deamon 228 * 229 * Parameters: 230 * In: 231 * pDevice - 232 * param - 233 * Out: 234 * 235 * Return Value: 236 * 237 */ 238static int hostap_add_sta(PSDevice pDevice, 239 struct viawget_hostapd_param *param) 240{ 241 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 242 unsigned int uNodeIndex; 243 244 245 if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { 246 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); 247 } 248 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); 249 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; 250 pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; 251// TODO listenInterval 252// pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1; 253 pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = FALSE; 254 pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; 255 256 // set max tx rate 257 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = 258 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; 259 // set max basic rate 260 pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; 261 // Todo: check sta preamble, if ap can't support, set status code 262 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = 263 WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); 264 265 pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid; 266 267 pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; 268 269 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID); 270 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", 271 param->sta_addr[0], 272 param->sta_addr[1], 273 param->sta_addr[2], 274 param->sta_addr[3], 275 param->sta_addr[4], 276 param->sta_addr[5] 277 ) ; 278 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n", 279 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); 280 281 return 0; 282} 283 284/* 285 * Description: 286 * get station info 287 * 288 * Parameters: 289 * In: 290 * pDevice - 291 * param - 292 * Out: 293 * 294 * Return Value: 295 * 296 */ 297 298static int hostap_get_info_sta(PSDevice pDevice, 299 struct viawget_hostapd_param *param) 300{ 301 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 302 unsigned int uNodeIndex; 303 304 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { 305 param->u.get_info_sta.inactive_sec = 306 (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; 307 308 //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts; 309 } 310 else { 311 return -ENOENT; 312 } 313 314 return 0; 315} 316 317/* 318 * Description: 319 * reset txexec 320 * 321 * Parameters: 322 * In: 323 * pDevice - 324 * param - 325 * Out: 326 * TURE, FALSE 327 * 328 * Return Value: 329 * 330 */ 331/* 332static int hostap_reset_txexc_sta(PSDevice pDevice, 333 struct viawget_hostapd_param *param) 334{ 335 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 336 unsigned int uNodeIndex; 337 338 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { 339 pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0; 340 } 341 else { 342 return -ENOENT; 343 } 344 345 return 0; 346} 347*/ 348 349/* 350 * Description: 351 * set station flag 352 * 353 * Parameters: 354 * In: 355 * pDevice - 356 * param - 357 * Out: 358 * 359 * Return Value: 360 * 361 */ 362static int hostap_set_flags_sta(PSDevice pDevice, 363 struct viawget_hostapd_param *param) 364{ 365 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 366 unsigned int uNodeIndex; 367 368 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { 369 pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; 370 pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; 371 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n", 372 (unsigned int) pMgmt->sNodeDBTable[uNodeIndex].dwFlags); 373 } 374 else { 375 return -ENOENT; 376 } 377 378 return 0; 379} 380 381 382 383/* 384 * Description: 385 * set generic element (wpa ie) 386 * 387 * Parameters: 388 * In: 389 * pDevice - 390 * param - 391 * Out: 392 * 393 * Return Value: 394 * 395 */ 396static int hostap_set_generic_element(PSDevice pDevice, 397 struct viawget_hostapd_param *param) 398{ 399 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 400 401 402 403 memcpy( pMgmt->abyWPAIE, 404 param->u.generic_elem.data, 405 param->u.generic_elem.len 406 ); 407 408 pMgmt->wWPAIELen = param->u.generic_elem.len; 409 410 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); 411 412 // disable wpa 413 if (pMgmt->wWPAIELen == 0) { 414 pMgmt->eAuthenMode = WMAC_AUTH_OPEN; 415 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n"); 416 } else { 417 // enable wpa 418 if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) || 419 (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) { 420 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; 421 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n"); 422 } else 423 return -EINVAL; 424 } 425 426 return 0; 427} 428 429/* 430 * Description: 431 * flush station nodes table. 432 * 433 * Parameters: 434 * In: 435 * pDevice - 436 * Out: 437 * 438 * Return Value: 439 * 440 */ 441 442static void hostap_flush_sta(PSDevice pDevice) 443{ 444 // reserved node index =0 for multicast node. 445 BSSvClearNodeDBTable(pDevice, 1); 446 pDevice->uAssocCount = 0; 447 448 return; 449} 450 451/* 452 * Description: 453 * set each stations encryption key 454 * 455 * Parameters: 456 * In: 457 * pDevice - 458 * param - 459 * Out: 460 * 461 * Return Value: 462 * 463 */ 464static int hostap_set_encryption(PSDevice pDevice, 465 struct viawget_hostapd_param *param, 466 int param_len) 467{ 468 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 469 DWORD dwKeyIndex = 0; 470 BYTE abyKey[MAX_KEY_LEN]; 471 BYTE abySeq[MAX_KEY_LEN]; 472 NDIS_802_11_KEY_RSC KeyRSC; 473 BYTE byKeyDecMode = KEY_CTL_WEP; 474 int ret = 0; 475 int iNodeIndex = -1; 476 int ii; 477 BOOL bKeyTableFull = FALSE; 478 WORD wKeyCtl = 0; 479 480 481 param->u.crypt.err = 0; 482/* 483 if (param_len != 484 (int) ((char *) param->u.crypt.key - (char *) param) + 485 param->u.crypt.key_len) 486 return -EINVAL; 487*/ 488 489 if (param->u.crypt.alg > WPA_ALG_CCMP) 490 return -EINVAL; 491 492 493 if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { 494 param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; 495 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); 496 return -EINVAL; 497 } 498 499 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 500 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 501 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 502 if (param->u.crypt.idx >= MAX_GROUP_KEY) 503 return -EINVAL; 504 iNodeIndex = 0; 505 506 } else { 507 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) { 508 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; 509 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); 510 return -EINVAL; 511 } 512 } 513 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex); 514 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg); 515 516 if (param->u.crypt.alg == WPA_ALG_NONE) { 517 518 if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == TRUE) { 519 if (KeybRemoveKey( pDevice, 520 &(pDevice->sKey), 521 param->sta_addr, 522 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex 523 ) == FALSE) { 524 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n"); 525 } 526 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE; 527 } 528 pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; 529 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; 530 pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; 531 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; 532 pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; 533 pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; 534 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; 535 memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 536 0, 537 MAX_KEY_LEN 538 ); 539 540 return ret; 541 } 542 543 memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); 544 // copy to node key tbl 545 pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; 546 pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; 547 memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 548 param->u.crypt.key, 549 param->u.crypt.key_len 550 ); 551 552 dwKeyIndex = (DWORD)(param->u.crypt.idx); 553 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { 554 pDevice->byKeyIndex = (BYTE)dwKeyIndex; 555 pDevice->bTransmitKey = TRUE; 556 dwKeyIndex |= (1 << 31); 557 } 558 559 if (param->u.crypt.alg == WPA_ALG_WEP) { 560 561 if ((pDevice->bEnable8021x == FALSE) || (iNodeIndex == 0)) { 562 KeybSetDefaultKey( pDevice, 563 &(pDevice->sKey), 564 dwKeyIndex & ~(BIT30 | USE_KEYRSC), 565 param->u.crypt.key_len, 566 NULL, 567 abyKey, 568 KEY_CTL_WEP 569 ); 570 571 } else { 572 // 8021x enable, individual key 573 dwKeyIndex |= (1 << 30); // set pairwise key 574 if (KeybSetKey(pDevice, 575 &(pDevice->sKey), 576 ¶m->sta_addr[0], 577 dwKeyIndex & ~(USE_KEYRSC), 578 param->u.crypt.key_len, 579 (PQWORD) &(KeyRSC), 580 (PBYTE)abyKey, 581 KEY_CTL_WEP 582 ) == TRUE) { 583 584 585 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE; 586 587 } else { 588 // Key Table Full 589 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE; 590 bKeyTableFull = TRUE; 591 } 592 } 593 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 594 pDevice->bEncryptionEnable = TRUE; 595 pMgmt->byCSSPK = KEY_CTL_WEP; 596 pMgmt->byCSSGK = KEY_CTL_WEP; 597 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; 598 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; 599 return ret; 600 } 601 602 if (param->u.crypt.seq) { 603 memcpy(&abySeq, param->u.crypt.seq, 8); 604 for (ii = 0 ; ii < 8 ; ii++) { 605 KeyRSC |= (abySeq[ii] << (ii * 8)); 606 } 607 dwKeyIndex |= 1 << 29; 608 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; 609 } 610 611 if (param->u.crypt.alg == WPA_ALG_TKIP) { 612 if (param->u.crypt.key_len != MAX_KEY_LEN) 613 return -EINVAL; 614 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 615 byKeyDecMode = KEY_CTL_TKIP; 616 pMgmt->byCSSPK = KEY_CTL_TKIP; 617 pMgmt->byCSSGK = KEY_CTL_TKIP; 618 } 619 620 if (param->u.crypt.alg == WPA_ALG_CCMP) { 621 if ((param->u.crypt.key_len != AES_KEY_LEN) || 622 (pDevice->byLocalID <= REV_ID_VT3253_A1)) 623 return -EINVAL; 624 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 625 byKeyDecMode = KEY_CTL_CCMP; 626 pMgmt->byCSSPK = KEY_CTL_CCMP; 627 pMgmt->byCSSGK = KEY_CTL_CCMP; 628 } 629 630 631 if (iNodeIndex == 0) { 632 KeybSetDefaultKey( pDevice, 633 &(pDevice->sKey), 634 dwKeyIndex, 635 param->u.crypt.key_len, 636 (PQWORD) &(KeyRSC), 637 abyKey, 638 byKeyDecMode 639 ); 640 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE; 641 642 } else { 643 dwKeyIndex |= (1 << 30); // set pairwise key 644 if (KeybSetKey(pDevice, 645 &(pDevice->sKey), 646 ¶m->sta_addr[0], 647 dwKeyIndex, 648 param->u.crypt.key_len, 649 (PQWORD) &(KeyRSC), 650 (PBYTE)abyKey, 651 byKeyDecMode 652 ) == TRUE) { 653 654 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE; 655 656 } else { 657 // Key Table Full 658 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE; 659 bKeyTableFull = TRUE; 660 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); 661 } 662 663 } 664 665 if (bKeyTableFull == TRUE) { 666 wKeyCtl &= 0x7F00; // clear all key control filed 667 wKeyCtl |= (byKeyDecMode << 4); 668 wKeyCtl |= (byKeyDecMode); 669 wKeyCtl |= 0x0044; // use group key for all address 670 wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int 671// Todo.. xxxxxx 672 //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); 673 } 674 675 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex); 676 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx, 677 param->u.crypt.key_len ); 678 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", 679 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 680 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], 681 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], 682 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], 683 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4] 684 ); 685 686 // set wep key 687 pDevice->bEncryptionEnable = TRUE; 688 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; 689 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; 690 pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; 691 pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; 692 693 return ret; 694} 695 696 697 698/* 699 * Description: 700 * get each stations encryption key 701 * 702 * Parameters: 703 * In: 704 * pDevice - 705 * param - 706 * Out: 707 * 708 * Return Value: 709 * 710 */ 711static int hostap_get_encryption(PSDevice pDevice, 712 struct viawget_hostapd_param *param, 713 int param_len) 714{ 715 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 716 int ret = 0; 717 int ii; 718 int iNodeIndex =0; 719 720 721 param->u.crypt.err = 0; 722 723 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 724 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 725 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 726 iNodeIndex = 0; 727 } else { 728 if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) { 729 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; 730 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); 731 return -EINVAL; 732 } 733 } 734 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); 735 memset(param->u.crypt.seq, 0, 8); 736 for (ii = 0 ; ii < 8 ; ii++) { 737 param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); 738 } 739 740 return ret; 741} 742 743 744/* 745 * Description: 746 * vt6656_hostap_ioctl main function supported for hostap deamon. 747 * 748 * Parameters: 749 * In: 750 * pDevice - 751 * iw_point - 752 * Out: 753 * 754 * Return Value: 755 * 756 */ 757 758int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p) 759{ 760 struct viawget_hostapd_param *param; 761 int ret = 0; 762 int ap_ioctl = 0; 763 764 if (p->length < sizeof(struct viawget_hostapd_param) || 765 p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer) 766 return -EINVAL; 767 768 param = kmalloc((int)p->length, (int)GFP_KERNEL); 769 if (param == NULL) 770 return -ENOMEM; 771 772 if (copy_from_user(param, p->pointer, p->length)) { 773 ret = -EFAULT; 774 goto out; 775 } 776 777 switch (param->cmd) { 778 case VIAWGET_HOSTAPD_SET_ENCRYPTION: 779 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n"); 780 spin_lock_irq(&pDevice->lock); 781 ret = hostap_set_encryption(pDevice, param, p->length); 782 spin_unlock_irq(&pDevice->lock); 783 break; 784 case VIAWGET_HOSTAPD_GET_ENCRYPTION: 785 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n"); 786 spin_lock_irq(&pDevice->lock); 787 ret = hostap_get_encryption(pDevice, param, p->length); 788 spin_unlock_irq(&pDevice->lock); 789 break; 790 case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR: 791 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n"); 792 return -EOPNOTSUPP; 793 break; 794 case VIAWGET_HOSTAPD_FLUSH: 795 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n"); 796 spin_lock_irq(&pDevice->lock); 797 hostap_flush_sta(pDevice); 798 spin_unlock_irq(&pDevice->lock); 799 break; 800 case VIAWGET_HOSTAPD_ADD_STA: 801 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n"); 802 spin_lock_irq(&pDevice->lock); 803 ret = hostap_add_sta(pDevice, param); 804 spin_unlock_irq(&pDevice->lock); 805 break; 806 case VIAWGET_HOSTAPD_REMOVE_STA: 807 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n"); 808 spin_lock_irq(&pDevice->lock); 809 ret = hostap_remove_sta(pDevice, param); 810 spin_unlock_irq(&pDevice->lock); 811 break; 812 case VIAWGET_HOSTAPD_GET_INFO_STA: 813 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n"); 814 ret = hostap_get_info_sta(pDevice, param); 815 ap_ioctl = 1; 816 break; 817/* 818 case VIAWGET_HOSTAPD_RESET_TXEXC_STA: 819 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n"); 820 ret = hostap_reset_txexc_sta(pDevice, param); 821 break; 822*/ 823 case VIAWGET_HOSTAPD_SET_FLAGS_STA: 824 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n"); 825 ret = hostap_set_flags_sta(pDevice, param); 826 break; 827 828 case VIAWGET_HOSTAPD_MLME: 829 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n"); 830 return -EOPNOTSUPP; 831 832 case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT: 833 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n"); 834 ret = hostap_set_generic_element(pDevice, param); 835 break; 836 837 case VIAWGET_HOSTAPD_SCAN_REQ: 838 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n"); 839 return -EOPNOTSUPP; 840 841 case VIAWGET_HOSTAPD_STA_CLEAR_STATS: 842 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n"); 843 return -EOPNOTSUPP; 844 845 default: 846 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n", 847 (int)param->cmd); 848 return -EOPNOTSUPP; 849 break; 850 } 851 852 853 if ((ret == 0) && ap_ioctl) { 854 if (copy_to_user(p->pointer, param, p->length)) { 855 ret = -EFAULT; 856 goto out; 857 } 858 } 859 860 out: 861 if (param != NULL) 862 kfree(param); 863 864 return ret; 865} 866