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.17-rc3 772 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 399/* 400 * Description: 401 * set each stations encryption key 402 * 403 * Parameters: 404 * In: 405 * pDevice - 406 * param - 407 * Out: 408 * 409 * Return Value: 410 * 411 */ 412static int hostap_set_encryption(PSDevice pDevice, 413 struct viawget_hostapd_param *param, 414 int param_len) 415{ 416 PSMgmtObject pMgmt = pDevice->pMgmt; 417 unsigned long dwKeyIndex = 0; 418 unsigned char abyKey[MAX_KEY_LEN]; 419 unsigned char abySeq[MAX_KEY_LEN]; 420 unsigned long long KeyRSC; 421 unsigned char byKeyDecMode = KEY_CTL_WEP; 422 int iNodeIndex = -1; 423 int ii; 424 bool bKeyTableFull = false; 425 unsigned short wKeyCtl = 0; 426 427 param->u.crypt.err = 0; 428 429 if (param->u.crypt.alg > WPA_ALG_CCMP) 430 return -EINVAL; 431 432 if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { 433 param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; 434 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); 435 return -EINVAL; 436 } 437 438 if (is_broadcast_ether_addr(param->sta_addr)) { 439 if (param->u.crypt.idx >= MAX_GROUP_KEY) 440 return -EINVAL; 441 iNodeIndex = 0; 442 443 } else { 444 if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { 445 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; 446 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); 447 return -EINVAL; 448 } 449 } 450 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d\n", iNodeIndex); 451 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d\n", param->u.crypt.alg); 452 453 if (param->u.crypt.alg == WPA_ALG_NONE) { 454 if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly) { 455 if (!KeybRemoveKey(&(pDevice->sKey), 456 param->sta_addr, 457 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, 458 pDevice->PortOffset)) { 459 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail\n"); 460 } 461 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; 462 } 463 pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; 464 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; 465 pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; 466 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; 467 pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; 468 pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; 469 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; 470 memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 471 0, 472 MAX_KEY_LEN 473); 474 475 return 0; 476 } 477 478 memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); 479 // copy to node key tbl 480 pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; 481 pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; 482 memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 483 param->u.crypt.key, 484 param->u.crypt.key_len 485); 486 487 dwKeyIndex = (unsigned long)(param->u.crypt.idx); 488 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { 489 pDevice->byKeyIndex = (unsigned char)dwKeyIndex; 490 pDevice->bTransmitKey = true; 491 dwKeyIndex |= (1 << 31); 492 } 493 494 if (param->u.crypt.alg == WPA_ALG_WEP) { 495 if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { 496 KeybSetDefaultKey(&(pDevice->sKey), 497 dwKeyIndex & ~(BIT30 | USE_KEYRSC), 498 param->u.crypt.key_len, 499 NULL, 500 abyKey, 501 KEY_CTL_WEP, 502 pDevice->PortOffset, 503 pDevice->byLocalID); 504 505 } else { 506 // 8021x enable, individual key 507 dwKeyIndex |= (1 << 30); // set pairwise key 508 if (KeybSetKey(&(pDevice->sKey), 509 &param->sta_addr[0], 510 dwKeyIndex & ~(USE_KEYRSC), 511 param->u.crypt.key_len, 512 (PQWORD) &(KeyRSC), 513 (unsigned char *)abyKey, 514 KEY_CTL_WEP, 515 pDevice->PortOffset, 516 pDevice->byLocalID)) { 517 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; 518 519 } else { 520 // Key Table Full 521 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; 522 bKeyTableFull = true; 523 } 524 } 525 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 526 pDevice->bEncryptionEnable = true; 527 pMgmt->byCSSPK = KEY_CTL_WEP; 528 pMgmt->byCSSGK = KEY_CTL_WEP; 529 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; 530 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; 531 return 0; 532 } 533 534 if (param->u.crypt.seq) { 535 memcpy(&abySeq, param->u.crypt.seq, 8); 536 for (ii = 0; ii < 8; ii++) 537 KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8); 538 539 dwKeyIndex |= 1 << 29; 540 pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; 541 } 542 543 if (param->u.crypt.alg == WPA_ALG_TKIP) { 544 if (param->u.crypt.key_len != MAX_KEY_LEN) 545 return -EINVAL; 546 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 547 byKeyDecMode = KEY_CTL_TKIP; 548 pMgmt->byCSSPK = KEY_CTL_TKIP; 549 pMgmt->byCSSGK = KEY_CTL_TKIP; 550 } 551 552 if (param->u.crypt.alg == WPA_ALG_CCMP) { 553 if ((param->u.crypt.key_len != AES_KEY_LEN) || 554 (pDevice->byLocalID <= REV_ID_VT3253_A1)) 555 return -EINVAL; 556 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 557 byKeyDecMode = KEY_CTL_CCMP; 558 pMgmt->byCSSPK = KEY_CTL_CCMP; 559 pMgmt->byCSSGK = KEY_CTL_CCMP; 560 } 561 562 if (iNodeIndex == 0) { 563 KeybSetDefaultKey(&(pDevice->sKey), 564 dwKeyIndex, 565 param->u.crypt.key_len, 566 (PQWORD) &(KeyRSC), 567 abyKey, 568 byKeyDecMode, 569 pDevice->PortOffset, 570 pDevice->byLocalID); 571 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; 572 573 } else { 574 dwKeyIndex |= (1 << 30); // set pairwise key 575 if (KeybSetKey(&(pDevice->sKey), 576 &param->sta_addr[0], 577 dwKeyIndex, 578 param->u.crypt.key_len, 579 (PQWORD) &(KeyRSC), 580 (unsigned char *)abyKey, 581 byKeyDecMode, 582 pDevice->PortOffset, 583 pDevice->byLocalID)) { 584 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; 585 586 } else { 587 // Key Table Full 588 pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; 589 bKeyTableFull = true; 590 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); 591 } 592 593 } 594 595 if (bKeyTableFull) { 596 wKeyCtl &= 0x7F00; // clear all key control filed 597 wKeyCtl |= (byKeyDecMode << 4); 598 wKeyCtl |= (byKeyDecMode); 599 wKeyCtl |= 0x0044; // use group key for all address 600 wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int 601 MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); 602 } 603 604 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d\n", iNodeIndex); 605 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d\n", param->u.crypt.idx, 606 param->u.crypt.key_len); 607 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx\n", 608 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 609 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], 610 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], 611 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], 612 pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4] 613); 614 615 // set wep key 616 pDevice->bEncryptionEnable = true; 617 pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; 618 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; 619 pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; 620 pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; 621 622 return 0; 623} 624 625/* 626 * Description: 627 * get each stations encryption key 628 * 629 * Parameters: 630 * In: 631 * pDevice - 632 * param - 633 * Out: 634 * 635 * Return Value: 636 * 637 */ 638static int hostap_get_encryption(PSDevice pDevice, 639 struct viawget_hostapd_param *param, 640 int param_len) 641{ 642 PSMgmtObject pMgmt = pDevice->pMgmt; 643 int ii; 644 int iNodeIndex = 0; 645 646 param->u.crypt.err = 0; 647 648 if (is_broadcast_ether_addr(param->sta_addr)) { 649 iNodeIndex = 0; 650 } else { 651 if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { 652 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; 653 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); 654 return -EINVAL; 655 } 656 } 657 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); 658 memset(param->u.crypt.seq, 0, 8); 659 for (ii = 0; ii < 8; ii++) 660 param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); 661 662 return 0; 663} 664 665/* 666 * Description: 667 * vt6655_hostap_ioctl main function supported for hostap deamon. 668 * 669 * Parameters: 670 * In: 671 * pDevice - 672 * iw_point - 673 * Out: 674 * 675 * Return Value: 676 * 677 */ 678int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) 679{ 680 struct viawget_hostapd_param *param; 681 int ret = 0; 682 int ap_ioctl = 0; 683 684 if (p->length < sizeof(struct viawget_hostapd_param) || 685 p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer) 686 return -EINVAL; 687 688 param = kmalloc((int)p->length, GFP_KERNEL); 689 if (param == NULL) 690 return -ENOMEM; 691 692 if (copy_from_user(param, p->pointer, p->length)) { 693 ret = -EFAULT; 694 goto out; 695 } 696 697 switch (param->cmd) { 698 case VIAWGET_HOSTAPD_SET_ENCRYPTION: 699 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION\n"); 700 spin_lock_irq(&pDevice->lock); 701 ret = hostap_set_encryption(pDevice, param, p->length); 702 spin_unlock_irq(&pDevice->lock); 703 break; 704 case VIAWGET_HOSTAPD_GET_ENCRYPTION: 705 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION\n"); 706 spin_lock_irq(&pDevice->lock); 707 ret = hostap_get_encryption(pDevice, param, p->length); 708 spin_unlock_irq(&pDevice->lock); 709 break; 710 case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR: 711 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR\n"); 712 ret = -EOPNOTSUPP; 713 goto out; 714 case VIAWGET_HOSTAPD_FLUSH: 715 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH\n"); 716 spin_lock_irq(&pDevice->lock); 717 hostap_flush_sta(pDevice); 718 spin_unlock_irq(&pDevice->lock); 719 break; 720 case VIAWGET_HOSTAPD_ADD_STA: 721 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA\n"); 722 spin_lock_irq(&pDevice->lock); 723 ret = hostap_add_sta(pDevice, param); 724 spin_unlock_irq(&pDevice->lock); 725 break; 726 case VIAWGET_HOSTAPD_REMOVE_STA: 727 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA\n"); 728 spin_lock_irq(&pDevice->lock); 729 ret = hostap_remove_sta(pDevice, param); 730 spin_unlock_irq(&pDevice->lock); 731 break; 732 case VIAWGET_HOSTAPD_GET_INFO_STA: 733 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA\n"); 734 ret = hostap_get_info_sta(pDevice, param); 735 ap_ioctl = 1; 736 break; 737 case VIAWGET_HOSTAPD_SET_FLAGS_STA: 738 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA\n"); 739 ret = hostap_set_flags_sta(pDevice, param); 740 break; 741 case VIAWGET_HOSTAPD_MLME: 742 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME\n"); 743 ret = -EOPNOTSUPP; 744 goto out; 745 case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT: 746 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT\n"); 747 ret = hostap_set_generic_element(pDevice, param); 748 break; 749 case VIAWGET_HOSTAPD_SCAN_REQ: 750 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ\n"); 751 ret = -EOPNOTSUPP; 752 goto out; 753 case VIAWGET_HOSTAPD_STA_CLEAR_STATS: 754 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS\n"); 755 ret = -EOPNOTSUPP; 756 goto out; 757 default: 758 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n", 759 (int)param->cmd); 760 ret = -EOPNOTSUPP; 761 goto out; 762 } 763 764 if ((ret == 0) && ap_ioctl) { 765 if (copy_to_user(p->pointer, param, p->length)) 766 ret = -EFAULT; 767 } 768 769out: 770 kfree(param); 771 return ret; 772}