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: ioctl.c 20 * 21 * Purpose: private ioctl functions 22 * 23 * Author: Lyndon Chen 24 * 25 * Date: Auguest 20, 2003 26 * 27 * Functions: 28 * 29 * Revision History: 30 * 31 */ 32 33#include "ioctl.h" 34#include "iocmd.h" 35#include "mac.h" 36#include "card.h" 37#include "hostap.h" 38#include "wpactl.h" 39#include "rf.h" 40 41#ifdef WPA_SM_Transtatus 42SWPAResult wpa_Result; 43#endif 44 45int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) 46{ 47 PSCmdRequest pReq = (PSCmdRequest)rq; 48 PSMgmtObject pMgmt = pDevice->pMgmt; 49 int result = 0; 50 PWLAN_IE_SSID pItemSSID; 51 SCmdBSSJoin sJoinCmd; 52 SCmdZoneTypeSet sZoneTypeCmd; 53 SCmdScan sScanCmd; 54 SCmdStartAP sStartAPCmd; 55 SCmdSetWEP sWEPCmd; 56 SCmdValue sValue; 57 SBSSIDList sList; 58 SNodeList sNodeList; 59 PSBSSIDList pList; 60 PSNodeList pNodeList; 61 unsigned int cbListCount; 62 PKnownBSS pBSS; 63 PKnownNodeDB pNode; 64 unsigned int ii, jj; 65 unsigned char abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; 66 unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 67 unsigned long dwKeyIndex = 0; 68 unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; 69 long ldBm; 70 71 pReq->wResult = 0; 72 73 switch (pReq->wCmdCode) { 74 case WLAN_CMD_BSS_SCAN: 75 pr_debug("WLAN_CMD_BSS_SCAN..begin\n"); 76 if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) { 77 result = -EFAULT; 78 break; 79 } 80 81 pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid; 82 if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) 83 return -EINVAL; 84 if (pItemSSID->len != 0) { 85 memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 86 memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); 87 } 88 89 if (pDevice->bMACSuspend == true) { 90 if (pDevice->bRadioOff == true) 91 CARDbRadioPowerOn(pDevice); 92 vMgrTimerInit(pDevice); 93 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); 94 add_timer(&pMgmt->sTimerSecondCallback); 95 pDevice->bMACSuspend = false; 96 } 97 spin_lock_irq(&pDevice->lock); 98 if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) 99 BSSvClearBSSList((void *)pDevice, false); 100 else 101 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); 102 103 if (pItemSSID->len != 0) 104 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); 105 else 106 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); 107 spin_unlock_irq(&pDevice->lock); 108 break; 109 110 case WLAN_CMD_ZONETYPE_SET: 111 /* mike add :can't support. */ 112 result = -EOPNOTSUPP; 113 break; 114 115 if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) { 116 result = -EFAULT; 117 break; 118 } 119 120 if (sZoneTypeCmd.bWrite == true) { 121 /* write zonetype */ 122 if (sZoneTypeCmd.ZoneType == ZoneType_USA) { 123 /* set to USA */ 124 pr_debug("set_ZoneType:USA\n"); 125 } else if (sZoneTypeCmd.ZoneType == ZoneType_Japan) { 126 /* set to Japan */ 127 pr_debug("set_ZoneType:Japan\n"); 128 } else if (sZoneTypeCmd.ZoneType == ZoneType_Europe) { 129 /* set to Europe */ 130 pr_debug("set_ZoneType:Europe\n"); 131 } 132 } else { 133 /* read zonetype */ 134 unsigned char zonetype = 0; 135 136 if (zonetype == 0x00) { /* USA */ 137 sZoneTypeCmd.ZoneType = ZoneType_USA; 138 } else if (zonetype == 0x01) { /* Japan */ 139 sZoneTypeCmd.ZoneType = ZoneType_Japan; 140 } else if (zonetype == 0x02) { /* Europe */ 141 sZoneTypeCmd.ZoneType = ZoneType_Europe; 142 } else { /* Unknown ZoneType */ 143 pr_err("Error:ZoneType[%x] Unknown ???\n", zonetype); 144 result = -EFAULT; 145 break; 146 } 147 if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) { 148 result = -EFAULT; 149 break; 150 } 151 } 152 break; 153 154 case WLAN_CMD_BSS_JOIN: 155 if (pDevice->bMACSuspend == true) { 156 if (pDevice->bRadioOff == true) 157 CARDbRadioPowerOn(pDevice); 158 vMgrTimerInit(pDevice); 159 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); 160 add_timer(&pMgmt->sTimerSecondCallback); 161 pDevice->bMACSuspend = false; 162 } 163 164 if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) { 165 result = -EFAULT; 166 break; 167 } 168 169 pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid; 170 if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) 171 return -EINVAL; 172 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 173 memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); 174 if (sJoinCmd.wBSSType == ADHOC) { 175 pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; 176 pr_debug("ioct set to adhoc mode\n"); 177 } else { 178 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; 179 pr_debug("ioct set to STA mode\n"); 180 } 181 if (sJoinCmd.bPSEnable == true) { 182 pDevice->ePSMode = WMAC_POWER_FAST; 183 pMgmt->wListenInterval = 2; 184 pr_debug("Power Saving On\n"); 185 } else { 186 pDevice->ePSMode = WMAC_POWER_CAM; 187 pMgmt->wListenInterval = 1; 188 pr_debug("Power Saving Off\n"); 189 } 190 191 if (sJoinCmd.bShareKeyAuth == true) { 192 pMgmt->bShareKeyAlgorithm = true; 193 pr_debug("Share Key\n"); 194 } else { 195 pMgmt->bShareKeyAlgorithm = false; 196 pr_debug("Open System\n"); 197 } 198 pDevice->uChannel = sJoinCmd.uChannel; 199 netif_stop_queue(pDevice->dev); 200 spin_lock_irq(&pDevice->lock); 201 pMgmt->eCurrState = WMAC_STATE_IDLE; 202 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); 203 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); 204 spin_unlock_irq(&pDevice->lock); 205 break; 206 207 case WLAN_CMD_SET_WEP: 208 pr_debug("WLAN_CMD_SET_WEP Key\n"); 209 memset(&sWEPCmd, 0, sizeof(SCmdSetWEP)); 210 if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) { 211 result = -EFAULT; 212 break; 213 } 214 if (sWEPCmd.bEnableWep != true) { 215 pDevice->bEncryptionEnable = false; 216 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 217 MACvDisableDefaultKey(pDevice->PortOffset); 218 pr_debug("WEP function disable\n"); 219 break; 220 } 221 222 for (ii = 0; ii < WLAN_WEP_NKEYS; ii++) { 223 if (sWEPCmd.bWepKeyAvailable[ii]) { 224 if (ii == sWEPCmd.byKeyIndex) 225 dwKeyIndex = ii | (1 << 31); 226 else 227 dwKeyIndex = ii; 228 229 KeybSetDefaultKey(&(pDevice->sKey), 230 dwKeyIndex, 231 sWEPCmd.auWepKeyLength[ii], 232 NULL, 233 (unsigned char *)&sWEPCmd.abyWepKey[ii][0], 234 KEY_CTL_WEP, 235 pDevice->PortOffset, 236 pDevice->byLocalID); 237 } 238 } 239 pDevice->byKeyIndex = sWEPCmd.byKeyIndex; 240 pDevice->bTransmitKey = true; 241 pDevice->bEncryptionEnable = true; 242 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 243 break; 244 245 case WLAN_CMD_GET_LINK: { 246 SCmdLinkStatus sLinkStatus; 247 248 pr_debug("WLAN_CMD_GET_LINK status\n"); 249 250 memset(&sLinkStatus, 0, sizeof(sLinkStatus)); 251 252 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) 253 sLinkStatus.wBSSType = ADHOC; 254 else 255 sLinkStatus.wBSSType = INFRA; 256 257 if (pMgmt->eCurrState == WMAC_STATE_JOINTED) 258 sLinkStatus.byState = ADHOC_JOINTED; 259 else 260 sLinkStatus.byState = ADHOC_STARTED; 261 262 sLinkStatus.uChannel = pMgmt->uCurrChannel; 263 if (pDevice->bLinkPass == true) { 264 sLinkStatus.bLink = true; 265 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; 266 memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len); 267 memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); 268 sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate; 269 pr_debug(" Link Success!\n"); 270 } else { 271 sLinkStatus.bLink = false; 272 sLinkStatus.uLinkRate = 0; 273 } 274 if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) { 275 result = -EFAULT; 276 break; 277 } 278 break; 279 } 280 case WLAN_CMD_GET_LISTLEN: 281 cbListCount = 0; 282 pBSS = &(pMgmt->sBSSList[0]); 283 for (ii = 0; ii < MAX_BSS_NUM; ii++) { 284 pBSS = &(pMgmt->sBSSList[ii]); 285 if (!pBSS->bActive) 286 continue; 287 cbListCount++; 288 } 289 sList.uItem = cbListCount; 290 if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) { 291 result = -EFAULT; 292 break; 293 } 294 pReq->wResult = 0; 295 break; 296 297 case WLAN_CMD_GET_LIST: 298 if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) { 299 result = -EFAULT; 300 break; 301 } 302 if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) { 303 result = -EINVAL; 304 break; 305 } 306 pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), 307 GFP_ATOMIC); 308 if (pList == NULL) { 309 result = -ENOMEM; 310 break; 311 } 312 pList->uItem = sList.uItem; 313 pBSS = &(pMgmt->sBSSList[0]); 314 for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { 315 pBSS = &(pMgmt->sBSSList[jj]); 316 if (pBSS->bActive) { 317 pList->sBSSIDList[ii].uChannel = pBSS->uChannel; 318 pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; 319 pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; 320 RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); 321 pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm; 322 memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); 323 pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; 324 memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1); 325 memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len); 326 if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) 327 pList->sBSSIDList[ii].byNetType = INFRA; 328 else 329 pList->sBSSIDList[ii].byNetType = ADHOC; 330 331 if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) 332 pList->sBSSIDList[ii].bWEPOn = true; 333 else 334 pList->sBSSIDList[ii].bWEPOn = false; 335 336 ii++; 337 if (ii >= pList->uItem) 338 break; 339 } 340 } 341 342 if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) { 343 result = -EFAULT; 344 break; 345 } 346 kfree(pList); 347 pReq->wResult = 0; 348 break; 349 350 case WLAN_CMD_GET_MIB: 351 if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) { 352 result = -EFAULT; 353 break; 354 } 355 break; 356 357 case WLAN_CMD_GET_STAT: 358 if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) { 359 result = -EFAULT; 360 break; 361 } 362 break; 363 364 case WLAN_CMD_STOP_MAC: 365 pr_debug("WLAN_CMD_STOP_MAC\n"); 366 netif_stop_queue(pDevice->dev); 367 368 spin_lock_irq(&pDevice->lock); 369 if (pDevice->bRadioOff == false) 370 CARDbRadioPowerOff(pDevice); 371 372 pDevice->bLinkPass = false; 373 memset(pMgmt->abyCurrBSSID, 0, 6); 374 pMgmt->eCurrState = WMAC_STATE_IDLE; 375 del_timer(&pDevice->sTimerCommand); 376 del_timer(&pMgmt->sTimerSecondCallback); 377 pDevice->bCmdRunning = false; 378 pDevice->bMACSuspend = true; 379 MACvIntDisable(pDevice->PortOffset); 380 spin_unlock_irq(&pDevice->lock); 381 break; 382 383 case WLAN_CMD_START_MAC: 384 pr_debug("WLAN_CMD_START_MAC\n"); 385 386 if (pDevice->bMACSuspend == true) { 387 if (pDevice->bRadioOff == true) 388 CARDbRadioPowerOn(pDevice); 389 vMgrTimerInit(pDevice); 390 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); 391 add_timer(&pMgmt->sTimerSecondCallback); 392 pDevice->bMACSuspend = false; 393 } 394 break; 395 396 case WLAN_CMD_SET_HOSTAPD: 397 pr_debug("WLAN_CMD_SET_HOSTAPD\n"); 398 399 if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { 400 result = -EFAULT; 401 break; 402 } 403 if (sValue.dwValue == 1) { 404 if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0) { 405 pr_debug("Enable HOSTAP\n"); 406 } else { 407 result = -EFAULT; 408 break; 409 } 410 } else { 411 vt6655_hostap_set_hostapd(pDevice, 0, 1); 412 pr_debug("Disable HOSTAP\n"); 413 } 414 break; 415 416 case WLAN_CMD_SET_HOSTAPD_STA: 417 pr_debug("WLAN_CMD_SET_HOSTAPD_STA\n"); 418 break; 419 420 case WLAN_CMD_SET_802_1X: 421 pr_debug("WLAN_CMD_SET_802_1X\n"); 422 if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { 423 result = -EFAULT; 424 break; 425 } 426 427 if (sValue.dwValue == 1) { 428 pDevice->bEnable8021x = true; 429 pr_debug("Enable 802.1x\n"); 430 } else { 431 pDevice->bEnable8021x = false; 432 pr_debug("Disable 802.1x\n"); 433 } 434 break; 435 436 case WLAN_CMD_SET_HOST_WEP: 437 pr_debug("WLAN_CMD_SET_HOST_WEP\n"); 438 if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { 439 result = -EFAULT; 440 break; 441 } 442 443 if (sValue.dwValue == 1) { 444 pDevice->bEnableHostWEP = true; 445 pr_debug("Enable HostWEP\n"); 446 } else { 447 pDevice->bEnableHostWEP = false; 448 pr_debug("Disable HostWEP\n"); 449 } 450 break; 451 452 case WLAN_CMD_SET_WPA: 453 pr_debug("WLAN_CMD_SET_WPA\n"); 454 455 if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { 456 result = -EFAULT; 457 break; 458 } 459 if (sValue.dwValue == 1) { 460 pr_debug("up wpadev\n"); 461 eth_hw_addr_inherit(pDevice->wpadev, pDevice->dev); 462 pDevice->bWPADEVUp = true; 463 } else { 464 pr_debug("close wpadev\n"); 465 pDevice->bWPADEVUp = false; 466 } 467 break; 468 469 case WLAN_CMD_AP_START: 470 pr_debug("WLAN_CMD_AP_START\n"); 471 if (pDevice->bRadioOff == true) { 472 CARDbRadioPowerOn(pDevice); 473 vMgrTimerInit(pDevice); 474 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); 475 add_timer(&pMgmt->sTimerSecondCallback); 476 } 477 if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) { 478 result = -EFAULT; 479 break; 480 } 481 482 if (sStartAPCmd.wBSSType == AP) { 483 pMgmt->eConfigMode = WMAC_CONFIG_AP; 484 pr_debug("ioct set to AP mode\n"); 485 } else { 486 pr_debug("ioct BSS type not set to AP mode\n"); 487 result = -EFAULT; 488 break; 489 } 490 491 if (sStartAPCmd.wBBPType == PHY80211g) 492 pMgmt->byAPBBType = PHY_TYPE_11G; 493 else if (sStartAPCmd.wBBPType == PHY80211a) 494 pMgmt->byAPBBType = PHY_TYPE_11A; 495 else 496 pMgmt->byAPBBType = PHY_TYPE_11B; 497 498 pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid; 499 if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) 500 return -EINVAL; 501 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 502 memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); 503 504 if ((sStartAPCmd.uChannel > 0) && (sStartAPCmd.uChannel <= 14)) 505 pDevice->uChannel = sStartAPCmd.uChannel; 506 507 if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000)) 508 pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt; 509 else 510 pMgmt->wIBSSBeaconPeriod = 100; 511 512 if (sStartAPCmd.bShareKeyAuth == true) { 513 pMgmt->bShareKeyAlgorithm = true; 514 pr_debug("Share Key\n"); 515 } else { 516 pMgmt->bShareKeyAlgorithm = false; 517 pr_debug("Open System\n"); 518 } 519 memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6); 520 521 if (sStartAPCmd.byBasicRate & BIT3) { 522 pMgmt->abyIBSSSuppRates[2] |= BIT7; 523 pMgmt->abyIBSSSuppRates[3] |= BIT7; 524 pMgmt->abyIBSSSuppRates[4] |= BIT7; 525 pMgmt->abyIBSSSuppRates[5] |= BIT7; 526 } else if (sStartAPCmd.byBasicRate & BIT2) { 527 pMgmt->abyIBSSSuppRates[2] |= BIT7; 528 pMgmt->abyIBSSSuppRates[3] |= BIT7; 529 pMgmt->abyIBSSSuppRates[4] |= BIT7; 530 } else if (sStartAPCmd.byBasicRate & BIT1) { 531 pMgmt->abyIBSSSuppRates[2] |= BIT7; 532 pMgmt->abyIBSSSuppRates[3] |= BIT7; 533 } else if (sStartAPCmd.byBasicRate & BIT1) { 534 pMgmt->abyIBSSSuppRates[2] |= BIT7; 535 } else { 536 /* default 1,2M */ 537 pMgmt->abyIBSSSuppRates[2] |= BIT7; 538 pMgmt->abyIBSSSuppRates[3] |= BIT7; 539 } 540 541 pr_debug("Support Rate= %*ph\n", 542 4, pMgmt->abyIBSSSuppRates + 2); 543 544 netif_stop_queue(pDevice->dev); 545 spin_lock_irq(&pDevice->lock); 546 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); 547 spin_unlock_irq(&pDevice->lock); 548 break; 549 550 case WLAN_CMD_GET_NODE_CNT: 551 cbListCount = 0; 552 pNode = &(pMgmt->sNodeDBTable[0]); 553 for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { 554 pNode = &(pMgmt->sNodeDBTable[ii]); 555 if (!pNode->bActive) 556 continue; 557 cbListCount++; 558 } 559 560 sNodeList.uItem = cbListCount; 561 if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) { 562 result = -EFAULT; 563 break; 564 } 565 pReq->wResult = 0; 566 break; 567 568 case WLAN_CMD_GET_NODE_LIST: 569 if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) { 570 result = -EFAULT; 571 break; 572 } 573 if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) { 574 result = -EINVAL; 575 break; 576 } 577 pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), 578 GFP_ATOMIC); 579 if (pNodeList == NULL) { 580 result = -ENOMEM; 581 break; 582 } 583 pNodeList->uItem = sNodeList.uItem; 584 pNode = &(pMgmt->sNodeDBTable[0]); 585 for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) { 586 pNode = &(pMgmt->sNodeDBTable[ii]); 587 if (pNode->bActive) { 588 pNodeList->sNodeList[jj].wAID = pNode->wAID; 589 memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN); 590 pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate; 591 pNodeList->sNodeList[jj].wInActiveCount = (unsigned short)pNode->uInActiveCount; 592 pNodeList->sNodeList[jj].wEnQueueCnt = (unsigned short)pNode->wEnQueueCnt; 593 pNodeList->sNodeList[jj].wFlags = (unsigned short)pNode->dwFlags; 594 pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable; 595 pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex; 596 pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength; 597 memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN); 598 pr_debug("key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", 599 pNodeList->sNodeList[jj].abyWepKey[0], 600 pNodeList->sNodeList[jj].abyWepKey[1], 601 pNodeList->sNodeList[jj].abyWepKey[2], 602 pNodeList->sNodeList[jj].abyWepKey[3], 603 pNodeList->sNodeList[jj].abyWepKey[4]); 604 pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback; 605 pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures; 606 pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts; 607 pNodeList->sNodeList[jj].wFailureRatio = (unsigned short)pNode->uFailureRatio; 608 jj++; 609 if (jj >= pNodeList->uItem) 610 break; 611 } 612 } 613 if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { 614 result = -EFAULT; 615 break; 616 } 617 kfree(pNodeList); 618 pReq->wResult = 0; 619 break; 620 621#ifdef WPA_SM_Transtatus 622 case 0xFF: 623 memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname)); 624 wpa_Result.proto = 0; 625 wpa_Result.key_mgmt = 0; 626 wpa_Result.eap_type = 0; 627 wpa_Result.authenticated = false; 628 pDevice->fWPA_Authened = false; 629 if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) { 630 result = -EFAULT; 631 break; 632 } 633 634 if (wpa_Result.authenticated == true) { 635#ifdef SndEvt_ToAPI 636 { 637 union iwreq_data wrqu; 638 639 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; 640 641 memset(&wrqu, 0, sizeof(wrqu)); 642 wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG; 643 wrqu.data.length = pItemSSID->len; 644 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID); 645 } 646#endif 647 pDevice->fWPA_Authened = true; /* is successful peer to wpa_Result.authenticated? */ 648 } 649 pReq->wResult = 0; 650 break; 651#endif 652 653 default: 654 pr_debug("Private command not support..\n"); 655 } 656 657 return result; 658} 659