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