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