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