linux/drivers/staging/vt6655/wmgr.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: wmgr.c
  21 *
  22 * Purpose: Handles the 802.11 management functions
  23 *
  24 * Author: Lyndon Chen
  25 *
  26 * Date: May 8, 2002
  27 *
  28 * Functions:
  29 *      nsMgrObjectInitial - Initialize Management Object data structure
  30 *      vMgrObjectReset - Reset Management Object data structure
  31 *      vMgrAssocBeginSta - Start associate function
  32 *      vMgrReAssocBeginSta - Start reassociate function
  33 *      vMgrDisassocBeginSta - Start disassociate function
  34 *      s_vMgrRxAssocRequest - Handle Rcv associate_request
  35 *      s_vMgrRxAssocResponse - Handle Rcv associate_response
  36 *      vMrgAuthenBeginSta - Start authentication function
  37 *      vMgrDeAuthenDeginSta - Start deauthentication function
  38 *      s_vMgrRxAuthentication - Handle Rcv authentication
  39 *      s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1
  40 *      s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2
  41 *      s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3
  42 *      s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4
  43 *      s_vMgrRxDisassociation - Handle Rcv disassociation
  44 *      s_vMgrRxBeacon - Handle Rcv Beacon
  45 *      vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS
  46 *      vMgrJoinBSSBegin - Join BSS function
  47 *      s_vMgrSynchBSS - Synch & adopt BSS parameters
  48 *      s_MgrMakeBeacon - Create Baecon frame
  49 *      s_MgrMakeProbeResponse - Create Probe Response frame
  50 *      s_MgrMakeAssocRequest - Create Associate Request frame
  51 *      s_MgrMakeReAssocRequest - Create ReAssociate Request frame
  52 *      s_vMgrRxProbeResponse - Handle Rcv probe_response
  53 *      s_vMrgRxProbeRequest - Handle Rcv probe_request
  54 *      bMgrPrepareBeaconToSend - Prepare Beacon frame
  55 *      s_vMgrLogStatus - Log 802.11 Status
  56 *      vMgrRxManagePacket - Rcv management frame dispatch function
  57 *      s_vMgrFormatTIM- Assembler TIM field of beacon
  58 *      vMgrTimerInit- Initial 1-sec and command call back funtions
  59 *
  60 * Revision History:
  61 *
  62 */
  63
  64#include "tmacro.h"
  65#include "desc.h"
  66#include "device.h"
  67#include "card.h"
  68#include "channel.h"
  69#include "80211hdr.h"
  70#include "80211mgr.h"
  71#include "wmgr.h"
  72#include "wcmd.h"
  73#include "mac.h"
  74#include "bssdb.h"
  75#include "power.h"
  76#include "datarate.h"
  77#include "baseband.h"
  78#include "rxtx.h"
  79#include "wpa.h"
  80#include "rf.h"
  81#include "iowpa.h"
  82
  83#define PLICE_DEBUG
  84
  85/*---------------------  Static Definitions -------------------------*/
  86
  87/*---------------------  Static Classes  ----------------------------*/
  88
  89/*---------------------  Static Variables  --------------------------*/
  90static int msglevel = MSG_LEVEL_INFO;
  91//static int          msglevel                =MSG_LEVEL_DEBUG;
  92
  93/*---------------------  Static Functions  --------------------------*/
  94//2008-8-4 <add> by chester
  95static bool ChannelExceedZoneType(
  96        PSDevice pDevice,
  97        unsigned char byCurrChannel
  98);
  99
 100// Association/diassociation functions
 101static
 102PSTxMgmtPacket
 103s_MgrMakeAssocRequest(
 104        PSDevice pDevice,
 105        PSMgmtObject pMgmt,
 106        unsigned char *pDAddr,
 107        unsigned short wCurrCapInfo,
 108        unsigned short wListenInterval,
 109        PWLAN_IE_SSID pCurrSSID,
 110        PWLAN_IE_SUPP_RATES pCurrRates,
 111        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
 112);
 113
 114static
 115void
 116s_vMgrRxAssocRequest(
 117        PSDevice pDevice,
 118        PSMgmtObject pMgmt,
 119        PSRxMgmtPacket pRxPacket,
 120        unsigned int uNodeIndex
 121);
 122
 123static
 124PSTxMgmtPacket
 125s_MgrMakeReAssocRequest(
 126        PSDevice pDevice,
 127        PSMgmtObject pMgmt,
 128        unsigned char *pDAddr,
 129        unsigned short wCurrCapInfo,
 130        unsigned short wListenInterval,
 131        PWLAN_IE_SSID pCurrSSID,
 132        PWLAN_IE_SUPP_RATES pCurrRates,
 133        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
 134);
 135
 136static
 137void
 138s_vMgrRxAssocResponse(
 139        PSDevice pDevice,
 140        PSMgmtObject pMgmt,
 141        PSRxMgmtPacket pRxPacket,
 142        bool bReAssocType
 143);
 144
 145static
 146void
 147s_vMgrRxDisassociation(
 148        PSDevice pDevice,
 149        PSMgmtObject pMgmt,
 150        PSRxMgmtPacket pRxPacket
 151);
 152
 153// Authentication/deauthen functions
 154static
 155void
 156s_vMgrRxAuthenSequence_1(
 157        PSDevice pDevice,
 158        PSMgmtObject pMgmt,
 159        PWLAN_FR_AUTHEN pFrame
 160);
 161
 162static
 163void
 164s_vMgrRxAuthenSequence_2(
 165        PSDevice pDevice,
 166        PSMgmtObject pMgmt,
 167        PWLAN_FR_AUTHEN pFrame
 168);
 169
 170static
 171void
 172s_vMgrRxAuthenSequence_3(
 173        PSDevice pDevice,
 174        PSMgmtObject pMgmt,
 175        PWLAN_FR_AUTHEN pFrame
 176);
 177
 178static
 179void
 180s_vMgrRxAuthenSequence_4(
 181        PSDevice pDevice,
 182        PSMgmtObject pMgmt,
 183        PWLAN_FR_AUTHEN pFrame
 184);
 185
 186static
 187void
 188s_vMgrRxAuthentication(
 189        PSDevice pDevice,
 190        PSMgmtObject pMgmt,
 191        PSRxMgmtPacket pRxPacket
 192);
 193
 194static
 195void
 196s_vMgrRxDeauthentication(
 197        PSDevice pDevice,
 198        PSMgmtObject pMgmt,
 199        PSRxMgmtPacket pRxPacket
 200);
 201
 202// Scan functions
 203// probe request/response functions
 204static
 205void
 206s_vMgrRxProbeRequest(
 207        PSDevice pDevice,
 208        PSMgmtObject pMgmt,
 209        PSRxMgmtPacket pRxPacket
 210);
 211
 212static
 213void
 214s_vMgrRxProbeResponse(
 215        PSDevice pDevice,
 216        PSMgmtObject pMgmt,
 217        PSRxMgmtPacket pRxPacket
 218);
 219
 220// beacon functions
 221static
 222void
 223s_vMgrRxBeacon(
 224        PSDevice pDevice,
 225        PSMgmtObject pMgmt,
 226        PSRxMgmtPacket pRxPacket,
 227        bool bInScan
 228);
 229
 230static
 231void
 232s_vMgrFormatTIM(
 233        PSMgmtObject pMgmt,
 234        PWLAN_IE_TIM pTIM
 235);
 236
 237static
 238PSTxMgmtPacket
 239s_MgrMakeBeacon(
 240        PSDevice pDevice,
 241        PSMgmtObject pMgmt,
 242        unsigned short wCurrCapInfo,
 243        unsigned short wCurrBeaconPeriod,
 244        unsigned int uCurrChannel,
 245        unsigned short wCurrATIMWinodw,
 246        PWLAN_IE_SSID pCurrSSID,
 247        unsigned char *pCurrBSSID,
 248        PWLAN_IE_SUPP_RATES pCurrSuppRates,
 249        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
 250);
 251
 252// Association response
 253static
 254PSTxMgmtPacket
 255s_MgrMakeAssocResponse(
 256        PSDevice pDevice,
 257        PSMgmtObject pMgmt,
 258        unsigned short wCurrCapInfo,
 259        unsigned short wAssocStatus,
 260        unsigned short wAssocAID,
 261        unsigned char *pDstAddr,
 262        PWLAN_IE_SUPP_RATES pCurrSuppRates,
 263        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
 264);
 265
 266// ReAssociation response
 267static
 268PSTxMgmtPacket
 269s_MgrMakeReAssocResponse(
 270        PSDevice pDevice,
 271        PSMgmtObject pMgmt,
 272        unsigned short wCurrCapInfo,
 273        unsigned short wAssocStatus,
 274        unsigned short wAssocAID,
 275        unsigned char *pDstAddr,
 276        PWLAN_IE_SUPP_RATES pCurrSuppRates,
 277        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
 278);
 279
 280// Probe response
 281static
 282PSTxMgmtPacket
 283s_MgrMakeProbeResponse(
 284        PSDevice pDevice,
 285        PSMgmtObject pMgmt,
 286        unsigned short wCurrCapInfo,
 287        unsigned short wCurrBeaconPeriod,
 288        unsigned int uCurrChannel,
 289        unsigned short wCurrATIMWinodw,
 290        unsigned char *pDstAddr,
 291        PWLAN_IE_SSID pCurrSSID,
 292        unsigned char *pCurrBSSID,
 293        PWLAN_IE_SUPP_RATES pCurrSuppRates,
 294        PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
 295        unsigned char byPHYType
 296);
 297
 298// received status
 299static
 300void
 301s_vMgrLogStatus(
 302        PSMgmtObject pMgmt,
 303        unsigned short wStatus
 304);
 305
 306static
 307void
 308s_vMgrSynchBSS(
 309        PSDevice      pDevice,
 310        unsigned int uBSSMode,
 311        PKnownBSS     pCurr,
 312        PCMD_STATUS  pStatus
 313);
 314
 315static bool
 316s_bCipherMatch(
 317        PKnownBSS                        pBSSNode,
 318        NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
 319        unsigned char *pbyCCSPK,
 320        unsigned char *pbyCCSGK
 321);
 322
 323static void  Encyption_Rebuild(
 324        PSDevice pDevice,
 325        PKnownBSS pCurr
 326);
 327
 328/*---------------------  Export Variables  --------------------------*/
 329
 330/*---------------------  Export Functions  --------------------------*/
 331
 332/*+
 333 *
 334 * Routine Description:
 335 *    Allocates and initializes the Management object.
 336 *
 337 * Return Value:
 338 *    Ndis_staus.
 339 *
 340 -*/
 341
 342void
 343vMgrObjectInit(
 344        void *hDeviceContext
 345)
 346{
 347        PSDevice     pDevice = (PSDevice)hDeviceContext;
 348        PSMgmtObject    pMgmt = pDevice->pMgmt;
 349        int ii;
 350
 351        pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
 352        pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
 353        pMgmt->uCurrChannel = pDevice->uChannel;
 354        for (ii = 0; ii < WLAN_BSSID_LEN; ii++) {
 355                pMgmt->abyDesireBSSID[ii] = 0xFF;
 356        }
 357        pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
 358        //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
 359        pMgmt->byCSSPK = KEY_CTL_NONE;
 360        pMgmt->byCSSGK = KEY_CTL_NONE;
 361        pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
 362        BSSvClearBSSList((void *)pDevice, false);
 363
 364        return;
 365}
 366
 367/*+
 368 *
 369 * Routine Description:
 370 *    Initializes timer object
 371 *
 372 * Return Value:
 373 *    Ndis_staus.
 374 *
 375 -*/
 376
 377void
 378vMgrTimerInit(
 379        void *hDeviceContext
 380)
 381{
 382        PSDevice     pDevice = (PSDevice)hDeviceContext;
 383        PSMgmtObject    pMgmt = pDevice->pMgmt;
 384
 385        init_timer(&pMgmt->sTimerSecondCallback);
 386        pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice;
 387        pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
 388        pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
 389
 390        init_timer(&pDevice->sTimerCommand);
 391        pDevice->sTimerCommand.data = (unsigned long) pDevice;
 392        pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
 393        pDevice->sTimerCommand.expires = RUN_AT(HZ);
 394
 395#ifdef TxInSleep
 396        init_timer(&pDevice->sTimerTxData);
 397        pDevice->sTimerTxData.data = (unsigned long) pDevice;
 398        pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
 399        pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
 400        pDevice->fTxDataInSleep = false;
 401        pDevice->IsTxDataTrigger = false;
 402        pDevice->nTxDataTimeCout = 0;
 403#endif
 404
 405        pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
 406        pDevice->uCmdDequeueIdx = 0;
 407        pDevice->uCmdEnqueueIdx = 0;
 408
 409        return;
 410}
 411
 412/*+
 413 *
 414 * Routine Description:
 415 *    Reset the management object structure.
 416 *
 417 * Return Value:
 418 *    None.
 419 *
 420 -*/
 421
 422void
 423vMgrObjectReset(
 424        void *hDeviceContext
 425)
 426{
 427        PSDevice         pDevice = (PSDevice)hDeviceContext;
 428        PSMgmtObject        pMgmt = pDevice->pMgmt;
 429
 430        pMgmt->eCurrMode = WMAC_MODE_STANDBY;
 431        pMgmt->eCurrState = WMAC_STATE_IDLE;
 432        pDevice->bEnablePSMode = false;
 433        // TODO: timer
 434
 435        return;
 436}
 437
 438/*+
 439 *
 440 * Routine Description:
 441 *    Start the station association procedure.  Namely, send an
 442 *    association request frame to the AP.
 443 *
 444 * Return Value:
 445 *    None.
 446 *
 447 -*/
 448
 449void
 450vMgrAssocBeginSta(
 451        void *hDeviceContext,
 452        PSMgmtObject pMgmt,
 453        PCMD_STATUS pStatus
 454)
 455{
 456        PSDevice             pDevice = (PSDevice)hDeviceContext;
 457        PSTxMgmtPacket          pTxPacket;
 458
 459        pMgmt->wCurrCapInfo = 0;
 460        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
 461        if (pDevice->bEncryptionEnable) {
 462                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
 463        }
 464        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
 465        if (pMgmt->wListenInterval == 0)
 466                pMgmt->wListenInterval = 1;    // at least one.
 467
 468        // ERP Phy (802.11g) should support short preamble.
 469        if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
 470                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
 471                if (CARDbIsShorSlotTime(pMgmt->pAdapter)) {
 472                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
 473                }
 474        } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
 475                if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
 476                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
 477                }
 478        }
 479        if (pMgmt->b11hEnable)
 480                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
 481
 482        /* build an assocreq frame and send it */
 483        pTxPacket = s_MgrMakeAssocRequest
 484                (
 485                        pDevice,
 486                        pMgmt,
 487                        pMgmt->abyCurrBSSID,
 488                        pMgmt->wCurrCapInfo,
 489                        pMgmt->wListenInterval,
 490                        (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
 491                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
 492                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
 493);
 494
 495        if (pTxPacket != NULL) {
 496                /* send the frame */
 497                *pStatus = csMgmt_xmit(pDevice, pTxPacket);
 498                if (*pStatus == CMD_STATUS_PENDING) {
 499                        pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
 500                        *pStatus = CMD_STATUS_SUCCESS;
 501                }
 502        } else
 503                *pStatus = CMD_STATUS_RESOURCES;
 504
 505        return;
 506}
 507
 508/*+
 509 *
 510 * Routine Description:
 511 *    Start the station re-association procedure.
 512 *
 513 * Return Value:
 514 *    None.
 515 *
 516 -*/
 517
 518void
 519vMgrReAssocBeginSta(
 520        void *hDeviceContext,
 521        PSMgmtObject pMgmt,
 522        PCMD_STATUS pStatus
 523)
 524{
 525        PSDevice             pDevice = (PSDevice)hDeviceContext;
 526        PSTxMgmtPacket          pTxPacket;
 527
 528        pMgmt->wCurrCapInfo = 0;
 529        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
 530        if (pDevice->bEncryptionEnable) {
 531                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
 532        }
 533
 534        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
 535
 536        if (pMgmt->wListenInterval == 0)
 537                pMgmt->wListenInterval = 1;    // at least one.
 538
 539        // ERP Phy (802.11g) should support short preamble.
 540        if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
 541                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
 542                if (CARDbIsShorSlotTime(pMgmt->pAdapter)) {
 543                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
 544                }
 545        } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
 546                if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
 547                        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
 548                }
 549        }
 550        if (pMgmt->b11hEnable)
 551                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
 552
 553        pTxPacket = s_MgrMakeReAssocRequest
 554                (
 555                        pDevice,
 556                        pMgmt,
 557                        pMgmt->abyCurrBSSID,
 558                        pMgmt->wCurrCapInfo,
 559                        pMgmt->wListenInterval,
 560                        (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
 561                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
 562                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
 563);
 564
 565        if (pTxPacket != NULL) {
 566                /* send the frame */
 567                *pStatus = csMgmt_xmit(pDevice, pTxPacket);
 568                if (*pStatus != CMD_STATUS_PENDING) {
 569                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
 570                } else {
 571                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
 572                }
 573        }
 574
 575        return;
 576}
 577
 578/*+
 579 *
 580 * Routine Description:
 581 *    Send an dis-association request frame to the AP.
 582 *
 583 * Return Value:
 584 *    None.
 585 *
 586 -*/
 587
 588void
 589vMgrDisassocBeginSta(
 590        void *hDeviceContext,
 591        PSMgmtObject pMgmt,
 592        unsigned char *abyDestAddress,
 593        unsigned short wReason,
 594        PCMD_STATUS pStatus
 595)
 596{
 597        PSDevice            pDevice = (PSDevice)hDeviceContext;
 598        PSTxMgmtPacket      pTxPacket = NULL;
 599        WLAN_FR_DISASSOC    sFrame;
 600
 601        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
 602        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
 603        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
 604
 605        // Setup the sFrame structure
 606        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
 607        sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
 608
 609        // format fixed field frame structure
 610        vMgrEncodeDisassociation(&sFrame);
 611
 612        // Setup the header
 613        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
 614                (
 615                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
 616                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
 617));
 618
 619        memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
 620        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
 621        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
 622
 623        // Set reason code
 624        *(sFrame.pwReason) = cpu_to_le16(wReason);
 625        pTxPacket->cbMPDULen = sFrame.len;
 626        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
 627
 628        // send the frame
 629        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
 630        if (*pStatus == CMD_STATUS_PENDING) {
 631                pMgmt->eCurrState = WMAC_STATE_IDLE;
 632                *pStatus = CMD_STATUS_SUCCESS;
 633        }
 634
 635        return;
 636}
 637
 638/*+
 639 *
 640 * Routine Description:(AP function)
 641 *    Handle incoming station association request frames.
 642 *
 643 * Return Value:
 644 *    None.
 645 *
 646 -*/
 647
 648static
 649void
 650s_vMgrRxAssocRequest(
 651        PSDevice pDevice,
 652        PSMgmtObject pMgmt,
 653        PSRxMgmtPacket pRxPacket,
 654        unsigned int uNodeIndex
 655)
 656{
 657        WLAN_FR_ASSOCREQ    sFrame;
 658        CMD_STATUS          Status;
 659        PSTxMgmtPacket      pTxPacket;
 660        unsigned short wAssocStatus = 0;
 661        unsigned short wAssocAID = 0;
 662        unsigned int uRateLen = WLAN_RATES_MAXLEN;
 663        unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
 664        unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
 665
 666        if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
 667                return;
 668        //  node index not found
 669        if (!uNodeIndex)
 670                return;
 671
 672        //check if node is authenticated
 673        //decode the frame
 674        memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
 675        memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
 676        memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
 677        sFrame.len = pRxPacket->cbMPDULen;
 678        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
 679
 680        vMgrDecodeAssocRequest(&sFrame);
 681
 682        if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
 683                pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
 684                pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
 685                pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
 686                pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
 687                        WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
 688                // Todo: check sta basic rate, if ap can't support, set status code
 689                if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
 690                        uRateLen = WLAN_RATES_MAXLEN_11B;
 691                }
 692                abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
 693                abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
 694                                                 (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
 695                                                 uRateLen);
 696                abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
 697                if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
 698                        abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
 699                                                            (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
 700                                                            uRateLen);
 701                } else {
 702                        abyCurrExtSuppRates[1] = 0;
 703                }
 704
 705                RATEvParseMaxRate((void *)pDevice,
 706                                  (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
 707                                  (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
 708                                  false, // do not change our basic rate
 709                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
 710                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
 711                                  &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
 712                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
 713                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
 714);
 715
 716                // set max tx rate
 717                pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
 718                        pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
 719#ifdef  PLICE_DEBUG
 720                printk("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
 721#endif
 722                // Todo: check sta preamble, if ap can't support, set status code
 723                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
 724                        WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
 725                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
 726                        WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
 727                pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
 728                wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
 729                wAssocAID = (unsigned short)uNodeIndex;
 730                // check if ERP support
 731                if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
 732                        pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
 733
 734                if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
 735                        // B only STA join
 736                        pDevice->bProtectMode = true;
 737                        pDevice->bNonERPPresent = true;
 738                }
 739                if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
 740                        pDevice->bBarkerPreambleMd = true;
 741                }
 742
 743                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
 744                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
 745                        sFrame.pHdr->sA3.abyAddr2[0],
 746                        sFrame.pHdr->sA3.abyAddr2[1],
 747                        sFrame.pHdr->sA3.abyAddr2[2],
 748                        sFrame.pHdr->sA3.abyAddr2[3],
 749                        sFrame.pHdr->sA3.abyAddr2[4],
 750                        sFrame.pHdr->sA3.abyAddr2[5]
 751                        );
 752                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
 753                        pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
 754        }//else { TODO: received STA under state1 handle }
 755        else {
 756                return;
 757        }
 758
 759        // assoc response reply..
 760        pTxPacket = s_MgrMakeAssocResponse
 761                (
 762                        pDevice,
 763                        pMgmt,
 764                        pMgmt->wCurrCapInfo,
 765                        wAssocStatus,
 766                        wAssocAID,
 767                        sFrame.pHdr->sA3.abyAddr2,
 768                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
 769                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
 770);
 771        if (pTxPacket != NULL) {
 772                if (pDevice->bEnableHostapd) {
 773                        return;
 774                }
 775                /* send the frame */
 776                Status = csMgmt_xmit(pDevice, pTxPacket);
 777                if (Status != CMD_STATUS_PENDING) {
 778                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
 779                } else {
 780                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
 781                }
 782
 783        }
 784
 785        return;
 786}
 787
 788/*+
 789 *
 790 * Description:(AP function)
 791 *      Handle incoming station re-association request frames.
 792 *
 793 * Parameters:
 794 *  In:
 795 *      pMgmt           - Management Object structure
 796 *      pRxPacket       - Received Packet
 797 *  Out:
 798 *      none
 799 *
 800 * Return Value: None.
 801 *
 802 -*/
 803
 804static
 805void
 806s_vMgrRxReAssocRequest(
 807        PSDevice pDevice,
 808        PSMgmtObject pMgmt,
 809        PSRxMgmtPacket pRxPacket,
 810        unsigned int uNodeIndex
 811)
 812{
 813        WLAN_FR_REASSOCREQ    sFrame;
 814        CMD_STATUS          Status;
 815        PSTxMgmtPacket      pTxPacket;
 816        unsigned short wAssocStatus = 0;
 817        unsigned short wAssocAID = 0;
 818        unsigned int    uRateLen = WLAN_RATES_MAXLEN;
 819        unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
 820        unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
 821
 822        if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
 823                return;
 824        //  node index not found
 825        if (!uNodeIndex)
 826                return;
 827        //check if node is authenticated
 828        //decode the frame
 829        memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
 830        sFrame.len = pRxPacket->cbMPDULen;
 831        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
 832        vMgrDecodeReassocRequest(&sFrame);
 833
 834        if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
 835                pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
 836                pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
 837                pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
 838                pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
 839                        WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
 840                // Todo: check sta basic rate, if ap can't support, set status code
 841
 842                if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
 843                        uRateLen = WLAN_RATES_MAXLEN_11B;
 844                }
 845
 846                abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
 847                abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
 848                                                 (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
 849                                                 uRateLen);
 850                abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
 851                if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
 852                        abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
 853                                                            (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
 854                                                            uRateLen);
 855                } else {
 856                        abyCurrExtSuppRates[1] = 0;
 857                }
 858
 859                RATEvParseMaxRate((void *)pDevice,
 860                                  (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
 861                                  (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
 862                                  false, // do not change our basic rate
 863                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
 864                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
 865                                  &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
 866                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
 867                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
 868);
 869
 870                // set max tx rate
 871                pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
 872                        pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
 873#ifdef  PLICE_DEBUG
 874                printk("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
 875#endif
 876                // Todo: check sta preamble, if ap can't support, set status code
 877                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
 878                        WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
 879                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
 880                        WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
 881                pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
 882                wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
 883                wAssocAID = (unsigned short)uNodeIndex;
 884
 885                // if suppurt ERP
 886                if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
 887                        pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
 888
 889                if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
 890                        // B only STA join
 891                        pDevice->bProtectMode = true;
 892                        pDevice->bNonERPPresent = true;
 893                }
 894                if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
 895                        pDevice->bBarkerPreambleMd = true;
 896                }
 897
 898                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
 899                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
 900                        sFrame.pHdr->sA3.abyAddr2[0],
 901                        sFrame.pHdr->sA3.abyAddr2[1],
 902                        sFrame.pHdr->sA3.abyAddr2[2],
 903                        sFrame.pHdr->sA3.abyAddr2[3],
 904                        sFrame.pHdr->sA3.abyAddr2[4],
 905                        sFrame.pHdr->sA3.abyAddr2[5]
 906                        );
 907                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
 908                        pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
 909
 910        }
 911
 912        // assoc response reply..
 913        pTxPacket = s_MgrMakeReAssocResponse
 914                (
 915                        pDevice,
 916                        pMgmt,
 917                        pMgmt->wCurrCapInfo,
 918                        wAssocStatus,
 919                        wAssocAID,
 920                        sFrame.pHdr->sA3.abyAddr2,
 921                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
 922                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
 923                        );
 924
 925        if (pTxPacket != NULL) {
 926                /* send the frame */
 927                if (pDevice->bEnableHostapd) {
 928                        return;
 929                }
 930                Status = csMgmt_xmit(pDevice, pTxPacket);
 931                if (Status != CMD_STATUS_PENDING) {
 932                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
 933                } else {
 934                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
 935                }
 936        }
 937        return;
 938}
 939
 940/*+
 941 *
 942 * Routine Description:
 943 *    Handle incoming association response frames.
 944 *
 945 * Return Value:
 946 *    None.
 947 *
 948 -*/
 949
 950static
 951void
 952s_vMgrRxAssocResponse(
 953        PSDevice pDevice,
 954        PSMgmtObject pMgmt,
 955        PSRxMgmtPacket pRxPacket,
 956        bool bReAssocType
 957)
 958{
 959        WLAN_FR_ASSOCRESP   sFrame;
 960        PWLAN_IE_SSID   pItemSSID;
 961        unsigned char *pbyIEs;
 962        viawget_wpa_header *wpahdr;
 963
 964        if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
 965            pMgmt->eCurrState == WMAC_STATE_ASSOC) {
 966                sFrame.len = pRxPacket->cbMPDULen;
 967                sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
 968                // decode the frame
 969                vMgrDecodeAssocResponse(&sFrame);
 970                if ((sFrame.pwCapInfo == 0) ||
 971                    (sFrame.pwStatus == 0) ||
 972                    (sFrame.pwAid == 0) ||
 973                    (sFrame.pSuppRates == 0)) {
 974                        DBG_PORT80(0xCC);
 975                        return;
 976                }
 977
 978                pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
 979                pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
 980                pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid);
 981                pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07;
 982
 983                pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6;
 984                pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength;
 985                pbyIEs = pMgmt->sAssocInfo.abyIEs;
 986                pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength;
 987                memcpy(pbyIEs, (sFrame.pBuf + 24 + 6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength);
 988
 989                // save values and set current BSS state
 990                if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
 991                        // set AID
 992                        pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
 993                        if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1)) {
 994                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
 995                        }
 996                        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14 | BIT15));
 997                        pMgmt->eCurrState = WMAC_STATE_ASSOC;
 998                        BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
 999                        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
1000                        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
1001                        pDevice->bLinkPass = true;
1002                        pDevice->uBBVGADiffCount = 0;
1003                        if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1004                                if (skb_tailroom(pDevice->skb) < (sizeof(viawget_wpa_header) + pMgmt->sAssocInfo.AssocInfo.ResponseIELength +
1005                                                                  pMgmt->sAssocInfo.AssocInfo.RequestIELength)) {    //data room not enough
1006                                        dev_kfree_skb(pDevice->skb);
1007                                        pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1008                                }
1009                                wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1010                                wpahdr->type = VIAWGET_ASSOC_MSG;
1011                                wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
1012                                wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1013                                memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len);
1014                                memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len,
1015                                       pbyIEs,
1016                                       wpahdr->resp_ie_len
1017);
1018                                skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
1019                                pDevice->skb->dev = pDevice->wpadev;
1020                                skb_reset_mac_header(pDevice->skb);
1021                                pDevice->skb->pkt_type = PACKET_HOST;
1022                                pDevice->skb->protocol = htons(ETH_P_802_2);
1023                                memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1024                                netif_rx(pDevice->skb);
1025                                pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1026                        }
1027
1028//2008-0409-07, <Add> by Einsn Liu
1029#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1030                        {
1031                                unsigned char buf[512];
1032                                size_t len;
1033                                union iwreq_data  wrqu;
1034                                int we_event;
1035
1036                                memset(buf, 0, 512);
1037
1038                                len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1039                                if (len)        {
1040                                        memcpy(buf, pMgmt->sAssocInfo.abyIEs, len);
1041                                        memset(&wrqu, 0, sizeof(wrqu));
1042                                        wrqu.data.length = len;
1043                                        we_event = IWEVASSOCREQIE;
1044                                        wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
1045                                }
1046
1047                                memset(buf, 0, 512);
1048                                len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
1049
1050                                if (len)        {
1051                                        memcpy(buf, pbyIEs, len);
1052                                        memset(&wrqu, 0, sizeof(wrqu));
1053                                        wrqu.data.length = len;
1054                                        we_event = IWEVASSOCRESPIE;
1055                                        wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
1056                                }
1057
1058                                memset(&wrqu, 0, sizeof(wrqu));
1059                                memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN);
1060                                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1061                                wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1062                        }
1063#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1064//End Add -- //2008-0409-07, <Add> by Einsn Liu
1065                } else {
1066                        if (bReAssocType) {
1067                                pMgmt->eCurrState = WMAC_STATE_IDLE;
1068                        } else {
1069                                // jump back to the auth state and indicate the error
1070                                pMgmt->eCurrState = WMAC_STATE_AUTH;
1071                        }
1072                        s_vMgrLogStatus(pMgmt, cpu_to_le16((*(sFrame.pwStatus))));
1073                }
1074
1075        }
1076
1077#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1078//need clear flags related to Networkmanager
1079
1080        pDevice->bwextcount = 0;
1081        pDevice->bWPASuppWextEnabled = false;
1082#endif
1083
1084        if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
1085                timer_expire(pDevice->sTimerCommand, 0);
1086        return;
1087}
1088
1089/*+
1090 *
1091 * Routine Description:
1092 *    Start the station authentication procedure.  Namely, send an
1093 *    authentication frame to the AP.
1094 *
1095 * Return Value:
1096 *    None.
1097 *
1098 -*/
1099
1100void
1101vMgrAuthenBeginSta(
1102        void *hDeviceContext,
1103        PSMgmtObject  pMgmt,
1104        PCMD_STATUS pStatus
1105)
1106{
1107        PSDevice     pDevice = (PSDevice)hDeviceContext;
1108        WLAN_FR_AUTHEN  sFrame;
1109        PSTxMgmtPacket  pTxPacket = NULL;
1110
1111        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1112        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1113        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1114        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1115        sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1116        vMgrEncodeAuthen(&sFrame);
1117        /* insert values */
1118        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1119                (
1120                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1121                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)
1122));
1123        memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
1124        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1125        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1126        if (pMgmt->bShareKeyAlgorithm)
1127                *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY);
1128        else
1129                *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM);
1130
1131        *(sFrame.pwAuthSequence) = cpu_to_le16(1);
1132        /* Adjust the length fields */
1133        pTxPacket->cbMPDULen = sFrame.len;
1134        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1135
1136        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
1137        if (*pStatus == CMD_STATUS_PENDING) {
1138                pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
1139                *pStatus = CMD_STATUS_SUCCESS;
1140        }
1141
1142        return;
1143}
1144
1145/*+
1146 *
1147 * Routine Description:
1148 *    Start the station(AP) deauthentication procedure.  Namely, send an
1149 *    deauthentication frame to the AP or Sta.
1150 *
1151 * Return Value:
1152 *    None.
1153 *
1154 -*/
1155
1156void
1157vMgrDeAuthenBeginSta(
1158        void *hDeviceContext,
1159        PSMgmtObject  pMgmt,
1160        unsigned char *abyDestAddress,
1161        unsigned short wReason,
1162        PCMD_STATUS pStatus
1163)
1164{
1165        PSDevice            pDevice = (PSDevice)hDeviceContext;
1166        WLAN_FR_DEAUTHEN    sFrame;
1167        PSTxMgmtPacket      pTxPacket = NULL;
1168
1169        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1170        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN);
1171        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1172        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1173        sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
1174        vMgrEncodeDeauthen(&sFrame);
1175        /* insert values */
1176        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1177                (
1178                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1179                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN)
1180));
1181
1182        memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
1183        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1184        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1185
1186        *(sFrame.pwReason) = cpu_to_le16(wReason);       // deauthen. bcs left BSS
1187        /* Adjust the length fields */
1188        pTxPacket->cbMPDULen = sFrame.len;
1189        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1190
1191        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
1192        if (*pStatus == CMD_STATUS_PENDING) {
1193                *pStatus = CMD_STATUS_SUCCESS;
1194        }
1195
1196        return;
1197}
1198
1199/*+
1200 *
1201 * Routine Description:
1202 *    Handle incoming authentication frames.
1203 *
1204 * Return Value:
1205 *    None.
1206 *
1207 -*/
1208
1209static
1210void
1211s_vMgrRxAuthentication(
1212        PSDevice pDevice,
1213        PSMgmtObject pMgmt,
1214        PSRxMgmtPacket pRxPacket
1215)
1216{
1217        WLAN_FR_AUTHEN  sFrame;
1218
1219        // we better be an AP or a STA in AUTHPENDING otherwise ignore
1220        if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP ||
1221              pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) {
1222                return;
1223        }
1224
1225        // decode the frame
1226        sFrame.len = pRxPacket->cbMPDULen;
1227        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1228        vMgrDecodeAuthen(&sFrame);
1229        switch (cpu_to_le16((*(sFrame.pwAuthSequence)))) {
1230        case 1:
1231                //AP function
1232                s_vMgrRxAuthenSequence_1(pDevice, pMgmt, &sFrame);
1233                break;
1234        case 2:
1235                s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame);
1236                break;
1237        case 3:
1238                //AP function
1239                s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame);
1240                break;
1241        case 4:
1242                s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
1243                break;
1244        default:
1245                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
1246                        cpu_to_le16((*(sFrame.pwAuthSequence))));
1247                break;
1248        }
1249        return;
1250}
1251
1252/*+
1253 *
1254 * Routine Description:
1255 *   Handles incoming authen frames with sequence 1.  Currently
1256 *   assumes we're an AP.  So far, no one appears to use authentication
1257 *   in Ad-Hoc mode.
1258 *
1259 * Return Value:
1260 *    None.
1261 *
1262 -*/
1263
1264static
1265void
1266s_vMgrRxAuthenSequence_1(
1267        PSDevice pDevice,
1268        PSMgmtObject pMgmt,
1269        PWLAN_FR_AUTHEN pFrame
1270)
1271{
1272        PSTxMgmtPacket      pTxPacket = NULL;
1273        unsigned int    uNodeIndex;
1274        WLAN_FR_AUTHEN      sFrame;
1275        PSKeyItem           pTransmitKey;
1276
1277        // Insert a Node entry
1278        if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
1279                BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
1280                memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2,
1281                       WLAN_ADDR_LEN);
1282        }
1283
1284        if (pMgmt->bShareKeyAlgorithm) {
1285                pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN;
1286                pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1;
1287        } else {
1288                pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
1289        }
1290
1291        // send auth reply
1292        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1293        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1294        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1295        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1296        sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1297        // format buffer structure
1298        vMgrEncodeAuthen(&sFrame);
1299        // insert values
1300        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1301                (
1302                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1303                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1304                        WLAN_SET_FC_ISWEP(0)
1305));
1306        memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
1307        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1308        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1309        *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1310        *(sFrame.pwAuthSequence) = cpu_to_le16(2);
1311
1312        if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) {
1313                if (pMgmt->bShareKeyAlgorithm)
1314                        *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1315                else
1316                        *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
1317        } else {
1318                if (pMgmt->bShareKeyAlgorithm)
1319                        *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
1320                else
1321                        *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1322        }
1323
1324        if (pMgmt->bShareKeyAlgorithm &&
1325            (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) {
1326                sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
1327                sFrame.len += WLAN_CHALLENGE_IE_LEN;
1328                sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
1329                sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
1330                memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
1331                // get group key
1332                if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) {
1333                        rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
1334                        rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
1335                }
1336                memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN);
1337        }
1338
1339        /* Adjust the length fields */
1340        pTxPacket->cbMPDULen = sFrame.len;
1341        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1342        // send the frame
1343        if (pDevice->bEnableHostapd) {
1344                return;
1345        }
1346        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
1347        if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
1348                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
1349        }
1350        return;
1351}
1352
1353/*+
1354 *
1355 * Routine Description:
1356 *   Handles incoming auth frames with sequence number 2.  Currently
1357 *   assumes we're a station.
1358 *
1359 *
1360 * Return Value:
1361 *    None.
1362 *
1363 -*/
1364
1365static
1366void
1367s_vMgrRxAuthenSequence_2(
1368        PSDevice pDevice,
1369        PSMgmtObject pMgmt,
1370        PWLAN_FR_AUTHEN pFrame
1371)
1372{
1373        WLAN_FR_AUTHEN      sFrame;
1374        PSTxMgmtPacket      pTxPacket = NULL;
1375
1376        switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) {
1377        case WLAN_AUTH_ALG_OPENSYSTEM:
1378                if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1379                        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
1380                        pMgmt->eCurrState = WMAC_STATE_AUTH;
1381                        timer_expire(pDevice->sTimerCommand, 0);
1382                } else {
1383                        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
1384                        s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1385                        pMgmt->eCurrState = WMAC_STATE_IDLE;
1386                }
1387                if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
1388//                spin_unlock_irq(&pDevice->lock);
1389//                vCommandTimerWait((void *)pDevice, 0);
1390//                spin_lock_irq(&pDevice->lock);
1391                }
1392
1393                break;
1394
1395        case WLAN_AUTH_ALG_SHAREDKEY:
1396
1397                if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1398                        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1399                        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1400                        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1401                        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1402                        sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1403                        // format buffer structure
1404                        vMgrEncodeAuthen(&sFrame);
1405                        // insert values
1406                        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1407                                (
1408                                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1409                                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1410                                        WLAN_SET_FC_ISWEP(1)
1411));
1412                        memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1413                        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1414                        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1415                        *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1416                        *(sFrame.pwAuthSequence) = cpu_to_le16(3);
1417                        *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1418                        sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
1419                        sFrame.len += WLAN_CHALLENGE_IE_LEN;
1420                        sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
1421                        sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
1422                        memcpy(sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN);
1423                        // Adjust the length fields
1424                        pTxPacket->cbMPDULen = sFrame.len;
1425                        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1426                        // send the frame
1427                        if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
1428                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
1429                        }
1430                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
1431                } else {
1432                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
1433                        if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
1434//                    spin_unlock_irq(&pDevice->lock);
1435//                    vCommandTimerWait((void *)pDevice, 0);
1436//                    spin_lock_irq(&pDevice->lock);
1437                        }
1438                        s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1439                }
1440                break;
1441        default:
1442                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
1443                break;
1444        }
1445        return;
1446}
1447
1448/*+
1449 *
1450 * Routine Description:
1451 *   Handles incoming authen frames with sequence 3.  Currently
1452 *   assumes we're an AP.  This function assumes the frame has
1453 *   already been successfully decrypted.
1454 *
1455 *
1456 * Return Value:
1457 *    None.
1458 *
1459 -*/
1460
1461static
1462void
1463s_vMgrRxAuthenSequence_3(
1464        PSDevice pDevice,
1465        PSMgmtObject pMgmt,
1466        PWLAN_FR_AUTHEN pFrame
1467)
1468{
1469        PSTxMgmtPacket      pTxPacket = NULL;
1470        unsigned int uStatusCode = 0;
1471        unsigned int uNodeIndex = 0;
1472        WLAN_FR_AUTHEN      sFrame;
1473
1474        if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
1475                uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
1476                goto reply;
1477        }
1478        if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
1479                if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) {
1480                        uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ;
1481                        goto reply;
1482                }
1483                if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) {
1484                        uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
1485                        goto reply;
1486                }
1487        } else {
1488                uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE;
1489                goto reply;
1490        }
1491
1492        if (uNodeIndex) {
1493                pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
1494                pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
1495        }
1496        uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
1497        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
1498
1499reply:
1500        // send auth reply
1501        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1502        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1503        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1504        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1505        sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1506        // format buffer structure
1507        vMgrEncodeAuthen(&sFrame);
1508        /* insert values */
1509        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1510                (
1511                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1512                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1513                        WLAN_SET_FC_ISWEP(0)
1514));
1515        memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
1516        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1517        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1518        *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1519        *(sFrame.pwAuthSequence) = cpu_to_le16(4);
1520        *(sFrame.pwStatus) = cpu_to_le16(uStatusCode);
1521
1522        /* Adjust the length fields */
1523        pTxPacket->cbMPDULen = sFrame.len;
1524        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1525        // send the frame
1526        if (pDevice->bEnableHostapd) {
1527                return;
1528        }
1529        if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
1530                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
1531        }
1532        return;
1533}
1534
1535/*+
1536 *
1537 * Routine Description:
1538 *   Handles incoming authen frames with sequence 4
1539 *
1540 *
1541 * Return Value:
1542 *    None.
1543 *
1544 -*/
1545static
1546void
1547s_vMgrRxAuthenSequence_4(
1548        PSDevice pDevice,
1549        PSMgmtObject pMgmt,
1550        PWLAN_FR_AUTHEN pFrame
1551)
1552{
1553        if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1554                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
1555                pMgmt->eCurrState = WMAC_STATE_AUTH;
1556                timer_expire(pDevice->sTimerCommand, 0);
1557        } else{
1558                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
1559                s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1560                pMgmt->eCurrState = WMAC_STATE_IDLE;
1561        }
1562
1563        if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
1564//        spin_unlock_irq(&pDevice->lock);
1565//        vCommandTimerWait((void *)pDevice, 0);
1566//        spin_lock_irq(&pDevice->lock);
1567        }
1568}
1569
1570/*+
1571 *
1572 * Routine Description:
1573 *   Handles incoming disassociation frames
1574 *
1575 *
1576 * Return Value:
1577 *    None.
1578 *
1579 -*/
1580
1581static
1582void
1583s_vMgrRxDisassociation(
1584        PSDevice pDevice,
1585        PSMgmtObject pMgmt,
1586        PSRxMgmtPacket pRxPacket
1587)
1588{
1589        WLAN_FR_DISASSOC    sFrame;
1590        unsigned int uNodeIndex = 0;
1591//    CMD_STATUS          CmdStatus;
1592        viawget_wpa_header *wpahdr;
1593
1594        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1595                // if is acting an AP..
1596                // a STA is leaving this BSS..
1597                sFrame.len = pRxPacket->cbMPDULen;
1598                sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1599                if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
1600                        BSSvRemoveOneNode(pDevice, uNodeIndex);
1601                } else {
1602                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
1603                }
1604        } else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1605                sFrame.len = pRxPacket->cbMPDULen;
1606                sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1607                vMgrDecodeDisassociation(&sFrame);
1608                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
1609                //TODO: do something let upper layer know or
1610                //try to send associate packet again because of inactivity timeout
1611                if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1612                        wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1613                        wpahdr->type = VIAWGET_DISASSOC_MSG;
1614                        wpahdr->resp_ie_len = 0;
1615                        wpahdr->req_ie_len = 0;
1616                        skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1617                        pDevice->skb->dev = pDevice->wpadev;
1618                        skb_reset_mac_header(pDevice->skb);
1619
1620                        pDevice->skb->pkt_type = PACKET_HOST;
1621                        pDevice->skb->protocol = htons(ETH_P_802_2);
1622                        memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1623                        netif_rx(pDevice->skb);
1624                        pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1625                }
1626
1627#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1628                {
1629                        union iwreq_data  wrqu;
1630                        memset(&wrqu, 0, sizeof(wrqu));
1631                        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1632                        printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1633                        wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1634                }
1635#endif
1636        }
1637        /* else, ignore it */
1638
1639        return;
1640}
1641
1642/*+
1643 *
1644 * Routine Description:
1645 *   Handles incoming deauthentication frames
1646 *
1647 *
1648 * Return Value:
1649 *    None.
1650 *
1651 -*/
1652
1653static
1654void
1655s_vMgrRxDeauthentication(
1656        PSDevice pDevice,
1657        PSMgmtObject pMgmt,
1658        PSRxMgmtPacket pRxPacket
1659)
1660{
1661        WLAN_FR_DEAUTHEN    sFrame;
1662        unsigned int uNodeIndex = 0;
1663        viawget_wpa_header *wpahdr;
1664
1665        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1666                //Todo:
1667                // if is acting an AP..
1668                // a STA is leaving this BSS..
1669                sFrame.len = pRxPacket->cbMPDULen;
1670                sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1671                if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
1672                        BSSvRemoveOneNode(pDevice, uNodeIndex);
1673                } else {
1674                        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
1675                }
1676        } else {
1677                if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1678                        sFrame.len = pRxPacket->cbMPDULen;
1679                        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1680                        vMgrDecodeDeauthen(&sFrame);
1681                        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
1682                        // TODO: update BSS list for specific BSSID if pre-authentication case
1683                        if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
1684                                             pMgmt->abyCurrBSSID)) {
1685                                if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
1686                                        pMgmt->sNodeDBTable[0].bActive = false;
1687                                        pMgmt->eCurrMode = WMAC_MODE_STANDBY;
1688                                        pMgmt->eCurrState = WMAC_STATE_IDLE;
1689                                        netif_stop_queue(pDevice->dev);
1690                                        pDevice->bLinkPass = false;
1691                                }
1692                        }
1693
1694                        if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1695                                wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1696                                wpahdr->type = VIAWGET_DISASSOC_MSG;
1697                                wpahdr->resp_ie_len = 0;
1698                                wpahdr->req_ie_len = 0;
1699                                skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1700                                pDevice->skb->dev = pDevice->wpadev;
1701                                skb_reset_mac_header(pDevice->skb);
1702                                pDevice->skb->pkt_type = PACKET_HOST;
1703                                pDevice->skb->protocol = htons(ETH_P_802_2);
1704                                memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1705                                netif_rx(pDevice->skb);
1706                                pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1707                        }
1708
1709#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1710                        {
1711                                union iwreq_data  wrqu;
1712                                memset(&wrqu, 0, sizeof(wrqu));
1713                                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1714                                PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
1715                                wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1716                        }
1717#endif
1718
1719                }
1720                /* else, ignore it.  TODO: IBSS authentication service
1721                   would be implemented here */
1722        }
1723        return;
1724}
1725
1726//2008-8-4 <add> by chester
1727/*+
1728 *
1729 * Routine Description:
1730 * check if current channel is match ZoneType.
1731 *for USA:1~11;
1732 *      Japan:1~13;
1733 *      Europe:1~13
1734 * Return Value:
1735 *               True:exceed;
1736 *                False:normal case
1737 -*/
1738static bool
1739ChannelExceedZoneType(
1740        PSDevice pDevice,
1741        unsigned char byCurrChannel
1742)
1743{
1744        bool exceed = false;
1745
1746        switch (pDevice->byZoneType) {
1747        case 0x00:                  //USA:1~11
1748                if ((byCurrChannel < 1) || (byCurrChannel > 11))
1749                        exceed = true;
1750                break;
1751        case 0x01:                  //Japan:1~13
1752        case 0x02:                  //Europe:1~13
1753                if ((byCurrChannel < 1) || (byCurrChannel > 13))
1754                        exceed = true;
1755                break;
1756        default:                    //reserve for other zonetype
1757                break;
1758        }
1759
1760        return exceed;
1761}
1762
1763/*+
1764 *
1765 * Routine Description:
1766 *   Handles and analysis incoming beacon frames.
1767 *
1768 *
1769 * Return Value:
1770 *    None.
1771 *
1772 -*/
1773
1774static
1775void
1776s_vMgrRxBeacon(
1777        PSDevice pDevice,
1778        PSMgmtObject pMgmt,
1779        PSRxMgmtPacket pRxPacket,
1780        bool bInScan
1781)
1782{
1783        PKnownBSS           pBSSList;
1784        WLAN_FR_BEACON      sFrame;
1785        QWORD               qwTSFOffset;
1786        bool bIsBSSIDEqual = false;
1787        bool bIsSSIDEqual = false;
1788        bool bTSFLargeDiff = false;
1789        bool bTSFOffsetPostive = false;
1790        bool bUpdateTSF = false;
1791        bool bIsAPBeacon = false;
1792        bool bIsChannelEqual = false;
1793        unsigned int uLocateByteIndex;
1794        unsigned char byTIMBitOn = 0;
1795        unsigned short wAIDNumber = 0;
1796        unsigned int uNodeIndex;
1797        QWORD               qwTimestamp, qwLocalTSF;
1798        QWORD               qwCurrTSF;
1799        unsigned short wStartIndex = 0;
1800        unsigned short wAIDIndex = 0;
1801        unsigned char byCurrChannel = pRxPacket->byRxChannel;
1802        ERPObject           sERP;
1803        unsigned int uRateLen = WLAN_RATES_MAXLEN;
1804        bool bChannelHit = false;
1805        bool bUpdatePhyParameter = false;
1806        unsigned char byIEChannel = 0;
1807
1808        memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
1809        sFrame.len = pRxPacket->cbMPDULen;
1810        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1811
1812        // decode the beacon frame
1813        vMgrDecodeBeacon(&sFrame);
1814
1815        if ((sFrame.pwBeaconInterval == 0) ||
1816            (sFrame.pwCapInfo == 0) ||
1817            (sFrame.pSSID == 0) ||
1818            (sFrame.pSuppRates == 0)) {
1819                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
1820                return;
1821        }
1822
1823        if (sFrame.pDSParms != NULL) {
1824                if (byCurrChannel > CB_MAX_CHANNEL_24G) {
1825                        // channel remapping to
1826                        byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
1827                } else {
1828                        byIEChannel = sFrame.pDSParms->byCurrChannel;
1829                }
1830                if (byCurrChannel != byIEChannel) {
1831                        // adjust channel info. bcs we rcv adjacent channel packets
1832                        bChannelHit = false;
1833                        byCurrChannel = byIEChannel;
1834                }
1835        } else {
1836                // no DS channel info
1837                bChannelHit = true;
1838        }
1839//2008-0730-01<Add>by MikeLiu
1840        if (ChannelExceedZoneType(pDevice, byCurrChannel))
1841                return;
1842
1843        if (sFrame.pERP != NULL) {
1844                sERP.byERP = sFrame.pERP->byContext;
1845                sERP.bERPExist = true;
1846
1847        } else {
1848                sERP.bERPExist = false;
1849                sERP.byERP = 0;
1850        }
1851
1852        pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
1853        if (pBSSList == NULL) {
1854                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon/insert: RxChannel = : %d\n", byCurrChannel);
1855                BSSbInsertToBSSList((void *)pDevice,
1856                                    sFrame.pHdr->sA3.abyAddr3,
1857                                    *sFrame.pqwTimestamp,
1858                                    *sFrame.pwBeaconInterval,
1859                                    *sFrame.pwCapInfo,
1860                                    byCurrChannel,
1861                                    sFrame.pSSID,
1862                                    sFrame.pSuppRates,
1863                                    sFrame.pExtSuppRates,
1864                                    &sERP,
1865                                    sFrame.pRSN,
1866                                    sFrame.pRSNWPA,
1867                                    sFrame.pIE_Country,
1868                                    sFrame.pIE_Quiet,
1869                                    sFrame.len - WLAN_HDR_ADDR3_LEN,
1870                                    sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
1871                                    (void *)pRxPacket
1872);
1873        } else {
1874//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "update bcn: RxChannel = : %d\n", byCurrChannel);
1875                BSSbUpdateToBSSList((void *)pDevice,
1876                                    *sFrame.pqwTimestamp,
1877                                    *sFrame.pwBeaconInterval,
1878                                    *sFrame.pwCapInfo,
1879                                    byCurrChannel,
1880                                    bChannelHit,
1881                                    sFrame.pSSID,
1882                                    sFrame.pSuppRates,
1883                                    sFrame.pExtSuppRates,
1884                                    &sERP,
1885                                    sFrame.pRSN,
1886                                    sFrame.pRSNWPA,
1887                                    sFrame.pIE_Country,
1888                                    sFrame.pIE_Quiet,
1889                                    pBSSList,
1890                                    sFrame.len - WLAN_HDR_ADDR3_LEN,
1891                                    sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
1892                                    (void *)pRxPacket
1893);
1894
1895        }
1896
1897        if (bInScan) {
1898                return;
1899        }
1900
1901        if (byCurrChannel == (unsigned char)pMgmt->uCurrChannel)
1902                bIsChannelEqual = true;
1903
1904        if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
1905                // if rx beacon without ERP field
1906                if (sERP.bERPExist) {
1907                        if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)) {
1908                                pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1909                                pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
1910                        }
1911                } else {
1912                        pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1913                        pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
1914                }
1915
1916                if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
1917                        if (!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
1918                                pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
1919                        if (!sERP.bERPExist)
1920                                pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
1921                }
1922
1923                // set to MAC&BBP
1924                if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
1925                        if (!pDevice->bProtectMode) {
1926                                MACvEnableProtectMD(pDevice->PortOffset);
1927                                pDevice->bProtectMode = true;
1928                        }
1929                }
1930        }
1931
1932        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
1933                return;
1934
1935        // check if BSSID the same
1936        if (memcmp(sFrame.pHdr->sA3.abyAddr3,
1937                   pMgmt->abyCurrBSSID,
1938                   WLAN_BSSID_LEN) == 0) {
1939                bIsBSSIDEqual = true;
1940
1941// 2008-05-21 <add> by Richardtai
1942                pDevice->uCurrRSSI = pRxPacket->uRSSI;
1943                pDevice->byCurrSQ = pRxPacket->bySQ;
1944
1945                if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
1946                        pMgmt->sNodeDBTable[0].uInActiveCount = 0;
1947                        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
1948                }
1949        }
1950        // check if SSID the same
1951        if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
1952                if (memcmp(sFrame.pSSID->abySSID,
1953                           ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
1954                           sFrame.pSSID->len
1955) == 0) {
1956                        bIsSSIDEqual = true;
1957                }
1958        }
1959
1960        if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) &&
1961            bIsBSSIDEqual &&
1962            bIsSSIDEqual &&
1963            (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
1964            (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
1965                // add state check to prevent reconnect fail since we'll receive Beacon
1966
1967                bIsAPBeacon = true;
1968
1969                if (pBSSList != NULL) {
1970                        // Compare PHY parameter setting
1971                        if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) {
1972                                bUpdatePhyParameter = true;
1973                                pMgmt->wCurrCapInfo = pBSSList->wCapInfo;
1974                        }
1975                        if (sFrame.pERP != NULL) {
1976                                if ((sFrame.pERP->byElementID == WLAN_EID_ERP) &&
1977                                    (pMgmt->byERPContext != sFrame.pERP->byContext)) {
1978                                        bUpdatePhyParameter = true;
1979                                        pMgmt->byERPContext = sFrame.pERP->byContext;
1980                                }
1981                        }
1982                        //
1983                        // Basic Rate Set may change dynamically
1984                        //
1985                        if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) {
1986                                uRateLen = WLAN_RATES_MAXLEN_11B;
1987                        }
1988                        pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
1989                                                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
1990                                                                uRateLen);
1991                        pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
1992                                                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
1993                                                                   uRateLen);
1994                        RATEvParseMaxRate((void *)pDevice,
1995                                          (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
1996                                          (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
1997                                          true,
1998                                          &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
1999                                          &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
2000                                          &(pMgmt->sNodeDBTable[0].wSuppRate),
2001                                          &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
2002                                          &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
2003                                );
2004                        if (bUpdatePhyParameter) {
2005                                CARDbSetPhyParameter(pMgmt->pAdapter,
2006                                                     pMgmt->eCurrentPHYMode,
2007                                                     pMgmt->wCurrCapInfo,
2008                                                     pMgmt->byERPContext,
2009                                                     pMgmt->abyCurrSuppRates,
2010                                                     pMgmt->abyCurrExtSuppRates
2011                                        );
2012                        }
2013                        if (sFrame.pIE_PowerConstraint != NULL) {
2014                                CARDvSetPowerConstraint(pMgmt->pAdapter,
2015                                                        (unsigned char) pBSSList->uChannel,
2016                                                        sFrame.pIE_PowerConstraint->byPower
2017);
2018                        }
2019                        if (sFrame.pIE_CHSW != NULL) {
2020                                CARDbChannelSwitch(pMgmt->pAdapter,
2021                                                   sFrame.pIE_CHSW->byMode,
2022                                                   get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode),
2023                                                   sFrame.pIE_CHSW->byCount
2024                                        );
2025
2026                        } else if (!bIsChannelEqual) {
2027                                set_channel(pMgmt->pAdapter, pBSSList->uChannel);
2028                        }
2029                }
2030        }
2031
2032//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2 \n");
2033        // check if CF field exists
2034        if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
2035                if (sFrame.pCFParms->wCFPDurRemaining > 0) {
2036                        // TODO: deal with CFP period to set NAV
2037                }
2038        }
2039
2040        HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
2041        LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
2042        HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF);
2043        LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF);
2044
2045        // check if beacon TSF larger or small than our local TSF
2046        if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
2047                if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) {
2048                        bTSFOffsetPostive = true;
2049                } else {
2050                        bTSFOffsetPostive = false;
2051                }
2052        } else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
2053                bTSFOffsetPostive = true;
2054        } else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
2055                bTSFOffsetPostive = false;
2056        }
2057
2058        if (bTSFOffsetPostive) {
2059                qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
2060        } else {
2061                qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
2062        }
2063
2064        if (HIDWORD(qwTSFOffset) != 0 ||
2065            (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE)) {
2066                bTSFLargeDiff = true;
2067        }
2068
2069        // if infra mode
2070        if (bIsAPBeacon) {
2071                // Infra mode: Local TSF always follow AP's TSF if Difference huge.
2072                if (bTSFLargeDiff)
2073                        bUpdateTSF = true;
2074
2075                if (pDevice->bEnablePSMode && (sFrame.pTIM != 0)) {
2076                        // deal with DTIM, analysis TIM
2077                        pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false;
2078                        pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
2079                        pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
2080                        wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
2081
2082                        // check if AID in TIM field bit on
2083                        // wStartIndex = N1
2084                        wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
2085                        // AIDIndex = N2
2086                        wAIDIndex = (wAIDNumber >> 3);
2087                        if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
2088                                uLocateByteIndex = wAIDIndex - wStartIndex;
2089                                // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
2090                                if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
2091                                        byTIMBitOn  = (0x01) << ((wAIDNumber) % 8);
2092                                        pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false;
2093                                } else {
2094                                        pMgmt->bInTIM = false;
2095                                }
2096                        } else {
2097                                pMgmt->bInTIM = false;
2098                        }
2099
2100                        if (pMgmt->bInTIM ||
2101                            (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
2102                                pMgmt->bInTIMWake = true;
2103                                // send out ps-poll packet
2104//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
2105                                if (pMgmt->bInTIM) {
2106                                        PSvSendPSPOLL((PSDevice)pDevice);
2107//                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
2108                                }
2109
2110                        } else {
2111                                pMgmt->bInTIMWake = false;
2112                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
2113                                if (!pDevice->bPWBitOn) {
2114                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
2115                                        if (PSbSendNullPacket(pDevice))
2116                                                pDevice->bPWBitOn = true;
2117                                }
2118                                if (PSbConsiderPowerDown(pDevice, false, false)) {
2119                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
2120                                }
2121                        }
2122
2123                }
2124
2125        }
2126        // if adhoc mode
2127        if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
2128                if (bIsBSSIDEqual) {
2129                        // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
2130                        if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
2131                                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2132
2133                        // adhoc mode:TSF updated only when beacon larger than local TSF
2134                        if (bTSFLargeDiff && bTSFOffsetPostive &&
2135                            (pMgmt->eCurrState == WMAC_STATE_JOINTED))
2136                                bUpdateTSF = true;
2137
2138                        // During dpc, already in spinlocked.
2139                        if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
2140                                // Update the STA, (Technically the Beacons of all the IBSS nodes
2141                                // should be identical, but that's not happening in practice.
2142                                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2143                                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2144                                                                        WLAN_RATES_MAXLEN_11B);
2145                                RATEvParseMaxRate((void *)pDevice,
2146                                                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2147                                                  NULL,
2148                                                  true,
2149                                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2150                                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2151                                                  &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2152                                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2153                                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2154                                        );
2155                                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2156                                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2157                                pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
2158                        } else {
2159                                // Todo, initial Node content
2160                                BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
2161
2162                                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2163                                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2164                                                                        WLAN_RATES_MAXLEN_11B);
2165                                RATEvParseMaxRate((void *)pDevice,
2166                                                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2167                                                  NULL,
2168                                                  true,
2169                                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2170                                                  &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2171                                                  &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2172                                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2173                                                  &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2174                                        );
2175
2176                                memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
2177                                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2178                                pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
2179#ifdef  PLICE_DEBUG
2180                                {
2181                                        printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex);
2182                                }
2183#endif
2184/*
2185  pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2186  if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
2187  pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
2188*/
2189                        }
2190
2191                        // if other stations joined, indicate connection to upper layer..
2192                        if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
2193                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
2194                                pMgmt->eCurrState = WMAC_STATE_JOINTED;
2195                                pDevice->bLinkPass = true;
2196                                if (netif_queue_stopped(pDevice->dev)) {
2197                                        netif_wake_queue(pDevice->dev);
2198                                }
2199                                pMgmt->sNodeDBTable[0].bActive = true;
2200                                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2201
2202                        }
2203                } else if (bIsSSIDEqual) {
2204                        // See other adhoc sta with the same SSID but BSSID is different.
2205                        // adpot this vars only when TSF larger then us.
2206                        if (bTSFLargeDiff && bTSFOffsetPostive) {
2207                                // we don't support ATIM under adhoc mode
2208                                // if (sFrame.pIBSSParms->wATIMWindow == 0) {
2209                                // adpot this vars
2210                                // TODO: check sFrame cap if privacy on, and support rate syn
2211                                memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
2212                                memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
2213                                pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
2214                                pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
2215                                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2216                                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2217                                                                        WLAN_RATES_MAXLEN_11B);
2218                                // set HW beacon interval and re-synchronizing....
2219                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
2220                                VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod);
2221                                CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF);
2222                                CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2223                                // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
2224                                MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
2225
2226                                CARDbSetPhyParameter(pMgmt->pAdapter,
2227                                                     pMgmt->eCurrentPHYMode,
2228                                                     pMgmt->wCurrCapInfo,
2229                                                     pMgmt->byERPContext,
2230                                                     pMgmt->abyCurrSuppRates,
2231                                                     pMgmt->abyCurrExtSuppRates);
2232
2233                                // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
2234                                // set highest basic rate
2235                                // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates);
2236                                // Prepare beacon frame
2237                                bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
2238                                //  }
2239                        }
2240                }
2241        }
2242        // endian issue ???
2243        // Update TSF
2244if (bUpdateTSF) {
2245                CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2246                CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
2247                CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2248                CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2249        }
2250
2251        return;
2252}
2253
2254/*+
2255 *
2256 * Routine Description:
2257 *   Instructs the hw to create a bss using the supplied
2258 *   attributes. Note that this implementation only supports Ad-Hoc
2259 *   BSS creation.
2260 *
2261 *
2262 * Return Value:
2263 *    CMD_STATUS
2264 *
2265 -*/
2266void
2267vMgrCreateOwnIBSS(
2268        void *hDeviceContext,
2269        PCMD_STATUS pStatus
2270)
2271{
2272        PSDevice            pDevice = (PSDevice)hDeviceContext;
2273        PSMgmtObject        pMgmt = pDevice->pMgmt;
2274        unsigned short wMaxBasicRate;
2275        unsigned short wMaxSuppRate;
2276        unsigned char byTopCCKBasicRate;
2277        unsigned char byTopOFDMBasicRate;
2278        QWORD               qwCurrTSF;
2279        unsigned int ii;
2280        unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
2281        unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
2282        unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2283        unsigned short wSuppRate;
2284
2285        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
2286
2287        if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2288                if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
2289                    (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
2290                    (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
2291                        // encryption mode error
2292                        *pStatus = CMD_STATUS_FAILURE;
2293                        return;
2294                }
2295        }
2296
2297        pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2298        pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
2299
2300        if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2301                pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
2302        } else {
2303                if (pDevice->byBBType == BB_TYPE_11G)
2304                        pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
2305                if (pDevice->byBBType == BB_TYPE_11B)
2306                        pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
2307                if (pDevice->byBBType == BB_TYPE_11A)
2308                        pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
2309        }
2310
2311        if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
2312                pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
2313                pMgmt->abyCurrExtSuppRates[1] = 0;
2314                for (ii = 0; ii < 4; ii++)
2315                        pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2316        } else {
2317                pMgmt->abyCurrSuppRates[1] = 8;
2318                pMgmt->abyCurrExtSuppRates[1] = 0;
2319                for (ii = 0; ii < 8; ii++)
2320                        pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2321        }
2322
2323        if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
2324                pMgmt->abyCurrSuppRates[1] = 8;
2325                pMgmt->abyCurrExtSuppRates[1] = 4;
2326                for (ii = 0; ii < 4; ii++)
2327                        pMgmt->abyCurrSuppRates[2+ii] =  abyCCK_RATE[ii];
2328                for (ii = 4; ii < 8; ii++)
2329                        pMgmt->abyCurrSuppRates[2+ii] =  abyOFDM_RATE[ii-4];
2330                for (ii = 0; ii < 4; ii++)
2331                        pMgmt->abyCurrExtSuppRates[2+ii] =  abyOFDM_RATE[ii+4];
2332        }
2333
2334        // Disable Protect Mode
2335        pDevice->bProtectMode = false;
2336        MACvDisableProtectMD(pDevice->PortOffset);
2337
2338        pDevice->bBarkerPreambleMd = false;
2339        MACvDisableBarkerPreambleMd(pDevice->PortOffset);
2340
2341        // Kyle Test 2003.11.04
2342
2343        // set HW beacon interval
2344        if (pMgmt->wIBSSBeaconPeriod == 0)
2345                pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
2346
2347        CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2348        // clear TSF counter
2349        VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
2350        // enable TSF counter
2351        VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
2352
2353        // set Next TBTT
2354        CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod);
2355
2356        pMgmt->uIBSSChannel = pDevice->uChannel;
2357
2358        if (pMgmt->uIBSSChannel == 0)
2359                pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
2360
2361        // set basic rate
2362
2363        RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2364                          (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true,
2365                          &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2366                          &byTopCCKBasicRate, &byTopOFDMBasicRate);
2367
2368        if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2369                pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
2370        }
2371
2372        if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2373                memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6);
2374                pMgmt->byIBSSDFSRecovery = 10;
2375                pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2376        }
2377
2378        // Adopt pre-configured IBSS vars to current vars
2379        pMgmt->eCurrState = WMAC_STATE_STARTED;
2380        pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
2381        pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2382        pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
2383        MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
2384        pDevice->uCurrRSSI = 0;
2385        pDevice->byCurrSQ = 0;
2386        //memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
2387        // ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
2388        memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2389        memcpy(pMgmt->abyCurrSSID,
2390               pMgmt->abyDesireSSID,
2391               ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
2392);
2393
2394        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2395                // AP mode BSSID = MAC addr
2396                memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
2397                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "AP beacon created BSSID:%pM\n",
2398                        pMgmt->abyCurrBSSID);
2399        }
2400
2401        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2402                // BSSID selected must be randomized as spec 11.1.3
2403                pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF) & 0x000000ff);
2404                pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0000ff00) >> 8);
2405                pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00ff0000) >> 16);
2406                pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00000ff0) >> 4);
2407                pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF) & 0x000ff000) >> 12);
2408                pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0ff00000) >> 20);
2409                pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
2410                pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
2411                pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
2412                pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
2413                pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
2414                pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
2415                pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
2416                pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
2417
2418                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Adhoc beacon created bssid:%pM\n",
2419                        pMgmt->abyCurrBSSID);
2420        }
2421
2422        // Set Capability Info
2423        pMgmt->wCurrCapInfo = 0;
2424
2425        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2426                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
2427                pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
2428                pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2429        }
2430
2431        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2432                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
2433        }
2434
2435        if (pDevice->bEncryptionEnable) {
2436                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
2437                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2438                        if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2439                                pMgmt->byCSSPK = KEY_CTL_CCMP;
2440                                pMgmt->byCSSGK = KEY_CTL_CCMP;
2441                        } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2442                                pMgmt->byCSSPK = KEY_CTL_TKIP;
2443                                pMgmt->byCSSGK = KEY_CTL_TKIP;
2444                        } else {
2445                                pMgmt->byCSSPK = KEY_CTL_NONE;
2446                                pMgmt->byCSSGK = KEY_CTL_WEP;
2447                        }
2448                } else {
2449                        pMgmt->byCSSPK = KEY_CTL_WEP;
2450                        pMgmt->byCSSGK = KEY_CTL_WEP;
2451                }
2452        }
2453
2454        pMgmt->byERPContext = 0;
2455
2456//    memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
2457
2458        if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2459                CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP);
2460        } else {
2461                CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
2462        }
2463
2464        CARDbSetPhyParameter(pMgmt->pAdapter,
2465                             pMgmt->eCurrentPHYMode,
2466                             pMgmt->wCurrCapInfo,
2467                             pMgmt->byERPContext,
2468                             pMgmt->abyCurrSuppRates,
2469                             pMgmt->abyCurrExtSuppRates
2470                );
2471
2472        CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod);
2473        // set channel and clear NAV
2474        set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel);
2475        pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2476
2477        if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
2478                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
2479        } else {
2480                pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
2481        }
2482
2483        if (pMgmt->b11hEnable &&
2484            (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
2485                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
2486        } else {
2487                pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1));
2488        }
2489
2490        pMgmt->eCurrState = WMAC_STATE_STARTED;
2491        // Prepare beacon to send
2492        if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) {
2493                *pStatus = CMD_STATUS_SUCCESS;
2494        }
2495
2496        return;
2497}
2498
2499/*+
2500 *
2501 * Routine Description:
2502 *   Instructs wmac to join a bss using the supplied attributes.
2503 *   The arguments may the BSSID or SSID and the rest of the
2504 *   attributes are obtained from the scan result of known bss list.
2505 *
2506 *
2507 * Return Value:
2508 *    None.
2509 *
2510 -*/
2511
2512void
2513vMgrJoinBSSBegin(
2514        void *hDeviceContext,
2515        PCMD_STATUS pStatus
2516)
2517{
2518        PSDevice     pDevice = (PSDevice)hDeviceContext;
2519        PSMgmtObject    pMgmt = pDevice->pMgmt;
2520        PKnownBSS       pCurr = NULL;
2521        unsigned int ii, uu;
2522        PWLAN_IE_SUPP_RATES pItemRates = NULL;
2523        PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
2524        PWLAN_IE_SSID   pItemSSID;
2525        unsigned int uRateLen = WLAN_RATES_MAXLEN;
2526        unsigned short wMaxBasicRate = RATE_1M;
2527        unsigned short wMaxSuppRate = RATE_1M;
2528        unsigned short wSuppRate;
2529        unsigned char byTopCCKBasicRate = RATE_1M;
2530        unsigned char byTopOFDMBasicRate = RATE_1M;
2531
2532        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
2533                if (pMgmt->sBSSList[ii].bActive)
2534                        break;
2535        }
2536
2537        if (ii == MAX_BSS_NUM) {
2538                *pStatus = CMD_STATUS_RESOURCES;
2539                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
2540                return;
2541        }
2542
2543        // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
2544        // Search known BSS list for prefer BSSID or SSID
2545
2546        pCurr = BSSpSearchBSSList(pDevice,
2547                                  pMgmt->abyDesireBSSID,
2548                                  pMgmt->abyDesireSSID,
2549                                  pMgmt->eConfigPHYMode
2550);
2551
2552        if (pCurr == NULL) {
2553                *pStatus = CMD_STATUS_RESOURCES;
2554                pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
2555                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
2556                return;
2557        }
2558
2559        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
2560        if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))) {
2561                if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
2562                        // patch for CISCO migration mode
2563/*
2564  if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2565  if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
2566  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
2567  // encryption mode error
2568  pMgmt->eCurrState = WMAC_STATE_IDLE;
2569  return;
2570  }
2571  } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2572  if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
2573  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
2574  // encryption mode error
2575  pMgmt->eCurrState = WMAC_STATE_IDLE;
2576  return;
2577  }
2578  }
2579*/
2580                }
2581
2582#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2583                Encyption_Rebuild(pDevice, pCurr);
2584#endif
2585                // Infrastructure BSS
2586                s_vMgrSynchBSS(pDevice,
2587                               WMAC_MODE_ESS_STA,
2588                               pCurr,
2589                               pStatus
2590);
2591
2592                if (*pStatus == CMD_STATUS_SUCCESS) {
2593                        // Adopt this BSS state vars in Mgmt Object
2594                        pMgmt->uCurrChannel = pCurr->uChannel;
2595
2596                        memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2597                        memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2598
2599                        if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
2600                                uRateLen = WLAN_RATES_MAXLEN_11B;
2601                        }
2602
2603                        pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
2604                        pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
2605
2606                        // Parse Support Rate IE
2607                        pItemRates->byElementID = WLAN_EID_SUPP_RATES;
2608                        pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2609                                                     pItemRates,
2610                                                     uRateLen);
2611
2612                        // Parse Extension Support Rate IE
2613                        pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
2614                        pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
2615                                                        pItemExtRates,
2616                                                        uRateLen);
2617                        // Stuffing Rate IE
2618                        if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
2619                                for (ii = 0; ii < (unsigned int)(8 - pItemRates->len);) {
2620                                        pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii];
2621                                        ii++;
2622                                        if (pItemExtRates->len <= ii)
2623                                                break;
2624                                }
2625                                pItemRates->len += (unsigned char)ii;
2626                                if (pItemExtRates->len - ii > 0) {
2627                                        pItemExtRates->len -= (unsigned char)ii;
2628                                        for (uu = 0; uu < pItemExtRates->len; uu++) {
2629                                                pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
2630                                        }
2631                                } else {
2632                                        pItemExtRates->len = 0;
2633                                }
2634                        }
2635
2636                        RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true,
2637                                          &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2638                                          &byTopCCKBasicRate, &byTopOFDMBasicRate);
2639
2640                        // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
2641                        // TODO: deal with if wCapInfo the PS-Pollable is on.
2642                        pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2643                        memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2644                        memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2645                        memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2646
2647                        pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
2648
2649                        pMgmt->eCurrState = WMAC_STATE_JOINTED;
2650                        // Adopt BSS state in Adapter Device Object
2651                        //pDevice->byOpMode = OP_MODE_INFRASTRUCTURE;
2652//            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2653
2654                        // Add current BSS to Candidate list
2655                        // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
2656                        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
2657                                bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
2658                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult);
2659                                if (!bResult) {
2660                                        vFlush_PMKID_Candidate((void *)pDevice);
2661                                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n");
2662                                        bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
2663                                }
2664                        }
2665
2666                        // Preamble type auto-switch: if AP can receive short-preamble cap,
2667                        // we can turn on too.
2668
2669                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join ESS\n");
2670
2671                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n");
2672                } else {
2673                        pMgmt->eCurrState = WMAC_STATE_IDLE;
2674                }
2675
2676        } else {
2677                // ad-hoc mode BSS
2678                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2679                        if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2680                                if (!WPA_SearchRSN(0, WPA_TKIP, pCurr)) {
2681                                        // encryption mode error
2682                                        pMgmt->eCurrState = WMAC_STATE_IDLE;
2683                                        return;
2684                                }
2685                        } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2686                                if (!WPA_SearchRSN(0, WPA_AESCCMP, pCurr)) {
2687                                        // encryption mode error
2688                                        pMgmt->eCurrState = WMAC_STATE_IDLE;
2689                                        return;
2690                                }
2691                        } else {
2692                                // encryption mode error
2693                                pMgmt->eCurrState = WMAC_STATE_IDLE;
2694                                return;
2695                        }
2696                }
2697
2698                s_vMgrSynchBSS(pDevice,
2699                               WMAC_MODE_IBSS_STA,
2700                               pCurr,
2701                               pStatus
2702);
2703
2704                if (*pStatus == CMD_STATUS_SUCCESS) {
2705                        // Adopt this BSS state vars in Mgmt Object
2706                        // TODO: check if CapInfo privacy on, but we don't..
2707                        pMgmt->uCurrChannel = pCurr->uChannel;
2708
2709                        // Parse Support Rate IE
2710                        pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2711                        pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2712                                                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2713                                                                WLAN_RATES_MAXLEN_11B);
2714                        // set basic rate
2715                        RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2716                                          NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2717                                          &byTopCCKBasicRate, &byTopOFDMBasicRate);
2718
2719                        pMgmt->wCurrCapInfo = pCurr->wCapInfo;
2720                        pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2721                        memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2722                        memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2723                        memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2724//          pMgmt->wCurrATIMWindow = pCurr->wATIMWindow;
2725                        MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
2726                        pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2727
2728                        pMgmt->eCurrState = WMAC_STATE_STARTED;
2729                        // Adopt BSS state in Adapter Device Object
2730                        //pDevice->byOpMode = OP_MODE_ADHOC;
2731//            pDevice->bLinkPass = true;
2732//            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2733
2734                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join IBSS ok:%pM\n",
2735                                pMgmt->abyCurrBSSID);
2736                        // Preamble type auto-switch: if AP can receive short-preamble cap,
2737                        // and if registry setting is short preamble we can turn on too.
2738
2739                        // Prepare beacon
2740                        bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
2741                } else {
2742                        pMgmt->eCurrState = WMAC_STATE_IDLE;
2743                }
2744        }
2745        return;
2746}
2747
2748/*+
2749 *
2750 * Routine Description:
2751 * Set HW to synchronize a specific BSS from known BSS list.
2752 *
2753 *
2754 * Return Value:
2755 *    PCM_STATUS
2756 *
2757 -*/
2758static
2759void
2760s_vMgrSynchBSS(
2761        PSDevice      pDevice,
2762        unsigned int uBSSMode,
2763        PKnownBSS     pCurr,
2764        PCMD_STATUS  pStatus
2765)
2766{
2767        CARD_PHY_TYPE   ePhyType = PHY_TYPE_11B;
2768        PSMgmtObject  pMgmt = pDevice->pMgmt;
2769//    int     ii;
2770        //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
2771        unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
2772        unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
2773        //6M,   9M,   12M,  48M
2774        unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2775        unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
2776
2777        *pStatus = CMD_STATUS_FAILURE;
2778
2779        if (!s_bCipherMatch(pCurr,
2780                           pDevice->eEncryptionStatus,
2781                           &(pMgmt->byCSSPK),
2782                           &(pMgmt->byCSSGK))) {
2783                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
2784                return;
2785        }
2786
2787        pMgmt->pCurrBSS = pCurr;
2788
2789        // if previous mode is IBSS.
2790        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2791                MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY);
2792                MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
2793        }
2794
2795        // Init the BSS informations
2796        pDevice->bCCK = true;
2797        pDevice->bProtectMode = false;
2798        MACvDisableProtectMD(pDevice->PortOffset);
2799        pDevice->bBarkerPreambleMd = false;
2800        MACvDisableBarkerPreambleMd(pDevice->PortOffset);
2801        pDevice->bNonERPPresent = false;
2802        pDevice->byPreambleType = 0;
2803        pDevice->wBasicRate = 0;
2804        // Set Basic Rate
2805        CARDbAddBasicRate((void *)pDevice, RATE_1M);
2806        // calculate TSF offset
2807        // TSF Offset = Received Timestamp TSF - Marked Local's TSF
2808        CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
2809
2810        CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval);
2811
2812        // set Next TBTT
2813        // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval
2814        CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval);
2815
2816        // set BSSID
2817        MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID);
2818
2819        MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
2820
2821        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = "
2822                "%pM\n", pMgmt->abyCurrBSSID);
2823
2824        if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
2825                if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) ||
2826                    (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2827                        ePhyType = PHY_TYPE_11A;
2828                } else {
2829                        return;
2830                }
2831        } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
2832                if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) ||
2833                    (pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
2834                    (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2835                        ePhyType = PHY_TYPE_11B;
2836                } else {
2837                        return;
2838                }
2839        } else {
2840                if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
2841                    (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2842                        ePhyType = PHY_TYPE_11G;
2843                } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) {
2844                        ePhyType = PHY_TYPE_11B;
2845                } else {
2846                        return;
2847                }
2848        }
2849
2850        if (ePhyType == PHY_TYPE_11A) {
2851                memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
2852                pMgmt->abyCurrExtSuppRates[1] = 0;
2853        } else if (ePhyType == PHY_TYPE_11B) {
2854                memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
2855                pMgmt->abyCurrExtSuppRates[1] = 0;
2856        } else {
2857                memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
2858                memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
2859        }
2860
2861        if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) {
2862                CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_INFRASTRUCTURE);
2863                // Add current BSS to Candidate list
2864                // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
2865                if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
2866                        CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap);
2867                }
2868        } else {
2869                CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC);
2870        }
2871
2872        if (!CARDbSetPhyParameter(pMgmt->pAdapter,
2873                                 ePhyType,
2874                                 pCurr->wCapInfo,
2875                                 pCurr->sERP.byERP,
2876                                 pMgmt->abyCurrSuppRates,
2877                                 pMgmt->abyCurrExtSuppRates)) {
2878                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
2879                return;
2880        }
2881        // set channel and clear NAV
2882        if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) {
2883                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
2884                return;
2885        }
2886
2887/*
2888  for (ii=0; ii<BB_VGA_LEVEL; ii++) {
2889  if (pCurr->ldBmMAX< pDevice->ldBmThreshold[ii]) {
2890  pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
2891  break;
2892  }
2893  }
2894
2895  if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
2896  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] \n",
2897  (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
2898  printk("RSSI[%d] NewGain[%d] OldGain[%d] \n",
2899  (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
2900  BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2901  }
2902  printk("ldBmMAX[%d] NewGain[%d] OldGain[%d] \n",
2903  (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
2904*/
2905        pMgmt->uCurrChannel = pCurr->uChannel;
2906        pMgmt->eCurrentPHYMode = ePhyType;
2907        pMgmt->byERPContext = pCurr->sERP.byERP;
2908        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel);
2909
2910        *pStatus = CMD_STATUS_SUCCESS;
2911
2912        return;
2913};
2914
2915//mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption
2916//                   ,need reset eAuthenMode and eEncryptionStatus
2917static void  Encyption_Rebuild(
2918        PSDevice pDevice,
2919        PKnownBSS pCurr
2920)
2921{
2922        PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
2923
2924        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selection,
2925            (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-select it according to real pairwise-key info.
2926                if (pCurr->bWPAValid)  {   //WPA-PSK
2927                        pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
2928                        if (pCurr->abyPKType[0] == WPA_TKIP) {
2929                                pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
2930                                PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
2931                        } else if (pCurr->abyPKType[0] == WPA_AESCCMP) {
2932                                pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
2933                                PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
2934                        }
2935                } else if (pCurr->bWPA2Valid) {  //WPA2-PSK
2936                        pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
2937                        if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
2938                                pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
2939                                PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
2940                        } else if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
2941                                pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
2942                                PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
2943                        }
2944                }
2945        }
2946        //  }
2947        return;
2948}
2949
2950/*+
2951 *
2952 * Routine Description:
2953 *  Format TIM field
2954 *
2955 *
2956 * Return Value:
2957 *    void
2958 *
2959 -*/
2960
2961static
2962void
2963s_vMgrFormatTIM(
2964        PSMgmtObject pMgmt,
2965        PWLAN_IE_TIM pTIM
2966)
2967{
2968        unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2969        unsigned char byMap;
2970        unsigned int ii, jj;
2971        bool bStartFound = false;
2972        bool bMulticast = false;
2973        unsigned short wStartIndex = 0;
2974        unsigned short wEndIndex = 0;
2975
2976        // Find size of partial virtual bitmap
2977        for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
2978                byMap = pMgmt->abyPSTxMap[ii];
2979                if (!ii) {
2980                        // Mask out the broadcast bit which is indicated separately.
2981                        bMulticast = (byMap & byMask[0]) != 0;
2982                        if (bMulticast) {
2983                                pMgmt->sNodeDBTable[0].bRxPSPoll = true;
2984                        }
2985                        byMap = 0;
2986                }
2987                if (byMap) {
2988                        if (!bStartFound) {
2989                                bStartFound = true;
2990                                wStartIndex = ii;
2991                        }
2992                        wEndIndex = ii;
2993                }
2994        }
2995
2996        // Round start index down to nearest even number
2997        wStartIndex &=  ~BIT0;
2998
2999        // Round end index up to nearest even number
3000        wEndIndex = ((wEndIndex + 1) & ~BIT0);
3001
3002        // Size of element payload
3003
3004        pTIM->len =  3 + (wEndIndex - wStartIndex) + 1;
3005
3006        // Fill in the Fixed parts of the TIM
3007        pTIM->byDTIMCount = pMgmt->byDTIMCount;
3008        pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
3009        pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
3010                (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
3011
3012        // Append variable part of TIM
3013
3014        for (ii = wStartIndex, jj = 0; ii <= wEndIndex; ii++, jj++) {
3015                pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
3016        }
3017
3018        // Aid = 0 don't used.
3019        pTIM->byVirtBitMap[0]  &= ~BIT0;
3020}
3021
3022/*+
3023 *
3024 * Routine Description:
3025 *  Constructs an Beacon frame(Ad-hoc mode)
3026 *
3027 *
3028 * Return Value:
3029 *    PTR to frame; or NULL on allocation failure
3030 *
3031 -*/
3032
3033static
3034PSTxMgmtPacket
3035s_MgrMakeBeacon(
3036        PSDevice pDevice,
3037        PSMgmtObject pMgmt,
3038        unsigned short wCurrCapInfo,
3039        unsigned short wCurrBeaconPeriod,
3040        unsigned int uCurrChannel,
3041        unsigned short wCurrATIMWinodw,
3042        PWLAN_IE_SSID pCurrSSID,
3043        unsigned char *pCurrBSSID,
3044        PWLAN_IE_SUPP_RATES pCurrSuppRates,
3045        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3046)
3047{
3048        PSTxMgmtPacket      pTxPacket = NULL;
3049        WLAN_FR_BEACON      sFrame;
3050        unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3051        unsigned char *pbyBuffer;
3052        unsigned int uLength = 0;
3053        PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
3054        unsigned int ii;
3055
3056        // prepare beacon frame
3057        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3058        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
3059        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3060        // Setup the sFrame structure.
3061        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3062        sFrame.len = WLAN_BEACON_FR_MAXLEN;
3063        vMgrEncodeBeacon(&sFrame);
3064        // Setup the header
3065        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3066                (
3067                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3068                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
3069));
3070
3071        if (pDevice->bEnablePSMode) {
3072                sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1));
3073        }
3074
3075        memcpy(sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
3076        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3077        memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3078        *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3079        *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3080        // Copy SSID
3081        sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3082        sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3083        memcpy(sFrame.pSSID,
3084               pCurrSSID,
3085               ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3086);
3087        // Copy the rate set
3088        sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3089        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3090        memcpy(sFrame.pSuppRates,
3091               pCurrSuppRates,
3092               ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3093);
3094        // DS parameter
3095        if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
3096                sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3097                sFrame.len += (1) + WLAN_IEHDR_LEN;
3098                sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3099                sFrame.pDSParms->len = 1;
3100                sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
3101        }
3102        // TIM field
3103        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
3104                sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
3105                sFrame.pTIM->byElementID = WLAN_EID_TIM;
3106                s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
3107                sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
3108        }
3109
3110        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3111                // IBSS parameter
3112                sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3113                sFrame.len += (2) + WLAN_IEHDR_LEN;
3114                sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3115                sFrame.pIBSSParms->len = 2;
3116                sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
3117                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3118                        /* RSN parameter */
3119                        sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3120                        sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3121                        sFrame.pRSNWPA->len = 12;
3122                        sFrame.pRSNWPA->abyOUI[0] = 0x00;
3123                        sFrame.pRSNWPA->abyOUI[1] = 0x50;
3124                        sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3125                        sFrame.pRSNWPA->abyOUI[3] = 0x01;
3126                        sFrame.pRSNWPA->wVersion = 1;
3127                        sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3128                        sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3129                        sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3130                        if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
3131                                sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
3132                        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
3133                                sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
3134                        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
3135                                sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
3136                        else
3137                                sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
3138
3139                        // Pairwise Key Cipher Suite
3140                        sFrame.pRSNWPA->wPKCount = 0;
3141                        // Auth Key Management Suite
3142                        *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0;
3143                        sFrame.pRSNWPA->len += 2;
3144
3145                        // RSN Capabilities
3146                        *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0;
3147                        sFrame.pRSNWPA->len += 2;
3148                        sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3149                }
3150        }
3151
3152        if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
3153                // Country IE
3154                pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
3155                set_country_IE(pMgmt->pAdapter, pbyBuffer);
3156                set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
3157                uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
3158                pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
3159                // Power Constrain IE
3160                ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
3161                ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
3162                ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
3163                pbyBuffer += (1) + WLAN_IEHDR_LEN;
3164                uLength += (1) + WLAN_IEHDR_LEN;
3165                if (pMgmt->bSwitchChannel) {
3166                        // Channel Switch IE
3167                        ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
3168                        ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
3169                        ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
3170                        ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
3171                        ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
3172                        pbyBuffer += (3) + WLAN_IEHDR_LEN;
3173                        uLength += (3) + WLAN_IEHDR_LEN;
3174                }
3175                // TPC report
3176                ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
3177                ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
3178                ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
3179                ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
3180                pbyBuffer += (2) + WLAN_IEHDR_LEN;
3181                uLength += (2) + WLAN_IEHDR_LEN;
3182                // IBSS DFS
3183                if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3184                        pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
3185                        pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
3186                        pIBSSDFS->len = 7;
3187                        memcpy(pIBSSDFS->abyDFSOwner,
3188                               pMgmt->abyIBSSDFSOwner,
3189                               6);
3190                        pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
3191                        pbyBuffer += (7) + WLAN_IEHDR_LEN;
3192                        uLength += (7) + WLAN_IEHDR_LEN;
3193                        for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) {
3194                                if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) {
3195                                        pbyBuffer += 2;
3196                                        uLength += 2;
3197                                        pIBSSDFS->len += 2;
3198                                }
3199                        }
3200                }
3201                sFrame.len += uLength;
3202        }
3203
3204        if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
3205                sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3206                sFrame.len += 1 + WLAN_IEHDR_LEN;
3207                sFrame.pERP->byElementID = WLAN_EID_ERP;
3208                sFrame.pERP->len = 1;
3209                sFrame.pERP->byContext = 0;
3210                if (pDevice->bProtectMode)
3211                        sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3212                if (pDevice->bNonERPPresent)
3213                        sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3214                if (pDevice->bBarkerPreambleMd)
3215                        sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3216        }
3217        if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3218                sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3219                sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3220                memcpy(sFrame.pExtSuppRates,
3221                       pCurrExtSuppRates,
3222                       ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3223);
3224        }
3225        // hostapd wpa/wpa2 IE
3226        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) {
3227                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3228                        if (pMgmt->wWPAIELen != 0) {
3229                                sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3230                                memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3231                                sFrame.len += pMgmt->wWPAIELen;
3232                        }
3233                }
3234        }
3235
3236        /* Adjust the length fields */
3237        pTxPacket->cbMPDULen = sFrame.len;
3238        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3239
3240        return pTxPacket;
3241}
3242
3243/*+
3244 *
3245 * Routine Description:
3246 *  Constructs an Prob-response frame
3247 *
3248 *
3249 * Return Value:
3250 *    PTR to frame; or NULL on allocation failure
3251 *
3252 -*/
3253
3254PSTxMgmtPacket
3255s_MgrMakeProbeResponse(
3256        PSDevice pDevice,
3257        PSMgmtObject pMgmt,
3258        unsigned short wCurrCapInfo,
3259        unsigned short wCurrBeaconPeriod,
3260        unsigned int uCurrChannel,
3261        unsigned short wCurrATIMWinodw,
3262        unsigned char *pDstAddr,
3263        PWLAN_IE_SSID pCurrSSID,
3264        unsigned char *pCurrBSSID,
3265        PWLAN_IE_SUPP_RATES pCurrSuppRates,
3266        PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
3267        unsigned char byPHYType
3268)
3269{
3270        PSTxMgmtPacket      pTxPacket = NULL;
3271        WLAN_FR_PROBERESP   sFrame;
3272        unsigned char *pbyBuffer;
3273        unsigned int uLength = 0;
3274        PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
3275        unsigned int ii;
3276
3277        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3278        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
3279        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3280        // Setup the sFrame structure.
3281        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3282        sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
3283        vMgrEncodeProbeResponse(&sFrame);
3284        // Setup the header
3285        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3286                (
3287                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3288                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
3289));
3290        memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3291        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3292        memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3293        *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3294        *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3295
3296        if (byPHYType == BB_TYPE_11B) {
3297                *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
3298        }
3299
3300        // Copy SSID
3301        sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3302        sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3303        memcpy(sFrame.pSSID,
3304               pCurrSSID,
3305               ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3306);
3307        // Copy the rate set
3308        sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3309
3310        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3311        memcpy(sFrame.pSuppRates,
3312               pCurrSuppRates,
3313               ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3314);
3315
3316        // DS parameter
3317        if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
3318                sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3319                sFrame.len += (1) + WLAN_IEHDR_LEN;
3320                sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3321                sFrame.pDSParms->len = 1;
3322                sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
3323        }
3324
3325        if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3326                // IBSS parameter
3327                sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3328                sFrame.len += (2) + WLAN_IEHDR_LEN;
3329                sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3330                sFrame.pIBSSParms->len = 2;
3331                sFrame.pIBSSParms->wATIMWindow = 0;
3332        }
3333        if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
3334                sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3335                sFrame.len += 1 + WLAN_IEHDR_LEN;
3336                sFrame.pERP->byElementID = WLAN_EID_ERP;
3337                sFrame.pERP->len = 1;
3338                sFrame.pERP->byContext = 0;
3339                if (pDevice->bProtectMode)
3340                        sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3341                if (pDevice->bNonERPPresent)
3342                        sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3343                if (pDevice->bBarkerPreambleMd)
3344                        sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3345        }
3346
3347        if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
3348                // Country IE
3349                pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
3350                set_country_IE(pMgmt->pAdapter, pbyBuffer);
3351                set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
3352                uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
3353                pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
3354                // Power Constrain IE
3355                ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
3356                ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
3357                ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
3358                pbyBuffer += (1) + WLAN_IEHDR_LEN;
3359                uLength += (1) + WLAN_IEHDR_LEN;
3360                if (pMgmt->bSwitchChannel) {
3361                        // Channel Switch IE
3362                        ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
3363                        ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
3364                        ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
3365                        ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
3366                        ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
3367                        pbyBuffer += (3) + WLAN_IEHDR_LEN;
3368                        uLength += (3) + WLAN_IEHDR_LEN;
3369                }
3370                // TPC report
3371                ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
3372                ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
3373                ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
3374                ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
3375                pbyBuffer += (2) + WLAN_IEHDR_LEN;
3376                uLength += (2) + WLAN_IEHDR_LEN;
3377                // IBSS DFS
3378                if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3379                        pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
3380                        pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
3381                        pIBSSDFS->len = 7;
3382                        memcpy(pIBSSDFS->abyDFSOwner,
3383                               pMgmt->abyIBSSDFSOwner,
3384                               6);
3385                        pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
3386                        pbyBuffer += (7) + WLAN_IEHDR_LEN;
3387                        uLength += (7) + WLAN_IEHDR_LEN;
3388                        for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) {
3389                                if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) {
3390                                        pbyBuffer += 2;
3391                                        uLength += 2;
3392                                        pIBSSDFS->len += 2;
3393                                }
3394                        }
3395                }
3396                sFrame.len += uLength;
3397        }
3398
3399        if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3400                sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3401                sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3402                memcpy(sFrame.pExtSuppRates,
3403                       pCurrExtSuppRates,
3404                       ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3405);
3406        }
3407
3408        // hostapd wpa/wpa2 IE
3409        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) {
3410                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3411                        if (pMgmt->wWPAIELen != 0) {
3412                                sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3413                                memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3414                                sFrame.len += pMgmt->wWPAIELen;
3415                        }
3416                }
3417        }
3418
3419        // Adjust the length fields
3420        pTxPacket->cbMPDULen = sFrame.len;
3421        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3422
3423        return pTxPacket;
3424}
3425
3426/*+
3427 *
3428 * Routine Description:
3429 *  Constructs an association request frame
3430 *
3431 *
3432 * Return Value:
3433 *    A ptr to frame or NULL on allocation failure
3434 *
3435 -*/
3436
3437PSTxMgmtPacket
3438s_MgrMakeAssocRequest(
3439        PSDevice pDevice,
3440        PSMgmtObject pMgmt,
3441        unsigned char *pDAddr,
3442        unsigned short wCurrCapInfo,
3443        unsigned short wListenInterval,
3444        PWLAN_IE_SSID pCurrSSID,
3445        PWLAN_IE_SUPP_RATES pCurrRates,
3446        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3447)
3448{
3449        PSTxMgmtPacket      pTxPacket = NULL;
3450        WLAN_FR_ASSOCREQ    sFrame;
3451        unsigned char *pbyIEs;
3452        unsigned char *pbyRSN;
3453
3454        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3455        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3456        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3457        // Setup the sFrame structure.
3458        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3459        sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
3460        // format fixed field frame structure
3461        vMgrEncodeAssocRequest(&sFrame);
3462        // Setup the header
3463        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3464                (
3465                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3466                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
3467));
3468        memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3469        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3470        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3471
3472        // Set the capability and listen interval
3473        *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3474        *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3475
3476        // sFrame.len point to end of fixed field
3477        sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3478        sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3479        memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3480
3481        pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3482        pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3483        pbyIEs = pMgmt->sAssocInfo.abyIEs;
3484        memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3485        pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3486
3487        // Copy the rate set
3488        sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3489        if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4))
3490                sFrame.len += 4 + WLAN_IEHDR_LEN;
3491        else
3492                sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3493        memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3494
3495        // Copy the extension rate set
3496        if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3497                sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3498                sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3499                memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3500        }
3501
3502        pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3503        memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3504        pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3505
3506        // for 802.11h
3507        if (pMgmt->b11hEnable) {
3508                if (sFrame.pCurrPowerCap == NULL) {
3509                        sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len);
3510                        sFrame.len += (2 + WLAN_IEHDR_LEN);
3511                        sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY;
3512                        sFrame.pCurrPowerCap->len = 2;
3513                        CARDvGetPowerCapability(pMgmt->pAdapter,
3514                                                &(sFrame.pCurrPowerCap->byMinPower),
3515                                                &(sFrame.pCurrPowerCap->byMaxPower)
3516);
3517                }
3518                if (sFrame.pCurrSuppCh == NULL) {
3519                        sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len);
3520                        sFrame.len += set_support_channels(pMgmt->pAdapter, (unsigned char *)sFrame.pCurrSuppCh);
3521                }
3522        }
3523
3524        if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3525             (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3526             (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3527            (pMgmt->pCurrBSS != NULL)) {
3528                /* WPA IE */
3529                sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3530                sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3531                sFrame.pRSNWPA->len = 16;
3532                sFrame.pRSNWPA->abyOUI[0] = 0x00;
3533                sFrame.pRSNWPA->abyOUI[1] = 0x50;
3534                sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3535                sFrame.pRSNWPA->abyOUI[3] = 0x01;
3536                sFrame.pRSNWPA->wVersion = 1;
3537                //Group Key Cipher Suite
3538                sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3539                sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3540                sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3541                if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3542                        sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3543                } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3544                        sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3545                } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3546                        sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3547                } else {
3548                        sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3549                }
3550                // Pairwise Key Cipher Suite
3551                sFrame.pRSNWPA->wPKCount = 1;
3552                sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3553                sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3554                sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3555                if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3556                        sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3557                } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3558                        sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3559                } else {
3560                        sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3561                }
3562                // Auth Key Management Suite
3563                pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3564                *pbyRSN++ = 0x01;
3565                *pbyRSN++ = 0x00;
3566                *pbyRSN++ = 0x00;
3567
3568                *pbyRSN++ = 0x50;
3569                *pbyRSN++ = 0xf2;
3570                if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
3571                        *pbyRSN++ = WPA_AUTH_PSK;
3572                } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
3573                        *pbyRSN++ = WPA_AUTH_IEEE802_1X;
3574                } else {
3575                        *pbyRSN++ = WPA_NONE;
3576                }
3577
3578                sFrame.pRSNWPA->len += 6;
3579
3580                // RSN Capabilities
3581
3582                *pbyRSN++ = 0x00;
3583                *pbyRSN++ = 0x00;
3584                sFrame.pRSNWPA->len += 2;
3585
3586                sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3587                // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3588                pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3589                memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3590                pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3591
3592        } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3593                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3594                   (pMgmt->pCurrBSS != NULL)) {
3595                unsigned int ii;
3596                unsigned short *pwPMKID;
3597
3598                // WPA IE
3599                sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3600                sFrame.pRSN->byElementID = WLAN_EID_RSN;
3601                sFrame.pRSN->len = 6; //Version(2)+GK(4)
3602                sFrame.pRSN->wVersion = 1;
3603                //Group Key Cipher Suite
3604                sFrame.pRSN->abyRSN[0] = 0x00;
3605                sFrame.pRSN->abyRSN[1] = 0x0F;
3606                sFrame.pRSN->abyRSN[2] = 0xAC;
3607                if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3608                        sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3609                } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3610                        sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3611                } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3612                        sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3613                } else {
3614                        sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3615                }
3616
3617                // Pairwise Key Cipher Suite
3618                sFrame.pRSN->abyRSN[4] = 1;
3619                sFrame.pRSN->abyRSN[5] = 0;
3620                sFrame.pRSN->abyRSN[6] = 0x00;
3621                sFrame.pRSN->abyRSN[7] = 0x0F;
3622                sFrame.pRSN->abyRSN[8] = 0xAC;
3623                if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3624                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3625                } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3626                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3627                } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
3628                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3629                } else {
3630                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3631                }
3632                sFrame.pRSN->len += 6;
3633
3634                // Auth Key Management Suite
3635                sFrame.pRSN->abyRSN[10] = 1;
3636                sFrame.pRSN->abyRSN[11] = 0;
3637                sFrame.pRSN->abyRSN[12] = 0x00;
3638                sFrame.pRSN->abyRSN[13] = 0x0F;
3639                sFrame.pRSN->abyRSN[14] = 0xAC;
3640                if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
3641                        sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3642                } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
3643                        sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3644                } else {
3645                        sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3646                }
3647                sFrame.pRSN->len += 6;
3648
3649                // RSN Capabilities
3650                if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) {
3651                        memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3652                } else {
3653                        sFrame.pRSN->abyRSN[16] = 0;
3654                        sFrame.pRSN->abyRSN[17] = 0;
3655                }
3656                sFrame.pRSN->len += 2;
3657
3658                if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3659                        // RSN PMKID
3660                        pbyRSN = &sFrame.pRSN->abyRSN[18];
3661                        pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
3662                        *pwPMKID = 0;            // Initialize PMKID count
3663                        pbyRSN += 2;             // Point to PMKID list
3664                        for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3665                                if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) {
3666                                        (*pwPMKID)++;
3667                                        memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
3668                                        pbyRSN += 16;
3669                                }
3670                        }
3671                        if (*pwPMKID != 0) {
3672                                sFrame.pRSN->len += (2 + (*pwPMKID)*16);
3673                        }
3674                }
3675
3676                sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3677                // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3678                pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3679                memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
3680                pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3681        }
3682
3683        // Adjust the length fields
3684        pTxPacket->cbMPDULen = sFrame.len;
3685        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3686        return pTxPacket;
3687}
3688
3689/*+
3690 *
3691 * Routine Description:
3692 *  Constructs an re-association request frame
3693 *
3694 *
3695 * Return Value:
3696 *    A ptr to frame or NULL on allocation failure
3697 *
3698 -*/
3699
3700PSTxMgmtPacket
3701s_MgrMakeReAssocRequest(
3702        PSDevice pDevice,
3703        PSMgmtObject pMgmt,
3704        unsigned char *pDAddr,
3705        unsigned short wCurrCapInfo,
3706        unsigned short wListenInterval,
3707        PWLAN_IE_SSID pCurrSSID,
3708        PWLAN_IE_SUPP_RATES pCurrRates,
3709        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3710)
3711{
3712        PSTxMgmtPacket      pTxPacket = NULL;
3713        WLAN_FR_REASSOCREQ  sFrame;
3714        unsigned char *pbyIEs;
3715        unsigned char *pbyRSN;
3716
3717        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3718        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
3719        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3720        /* Setup the sFrame structure. */
3721        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3722        sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
3723
3724        // format fixed field frame structure
3725        vMgrEncodeReassocRequest(&sFrame);
3726
3727        /* Setup the header */
3728        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3729                (
3730                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3731                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
3732));
3733        memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3734        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3735        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3736
3737        /* Set the capability and listen interval */
3738        *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3739        *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3740
3741        memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3742        /* Copy the SSID */
3743        /* sFrame.len point to end of fixed field */
3744        sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3745        sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3746        memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3747
3748        pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3749        pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3750        pbyIEs = pMgmt->sAssocInfo.abyIEs;
3751        memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3752        pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3753
3754        /* Copy the rate set */
3755        /* sFrame.len point to end of SSID */
3756        sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3757        sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3758        memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3759
3760        // Copy the extension rate set
3761        if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3762                sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3763                sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3764                memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3765        }
3766
3767        pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3768        memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3769        pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3770
3771        if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3772             (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3773             (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3774            (pMgmt->pCurrBSS != NULL)) {
3775                /* WPA IE */
3776                sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3777                sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3778                sFrame.pRSNWPA->len = 16;
3779                sFrame.pRSNWPA->abyOUI[0] = 0x00;
3780                sFrame.pRSNWPA->abyOUI[1] = 0x50;
3781                sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3782                sFrame.pRSNWPA->abyOUI[3] = 0x01;
3783                sFrame.pRSNWPA->wVersion = 1;
3784                //Group Key Cipher Suite
3785                sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3786                sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3787                sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3788                if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3789                        sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3790                } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3791                        sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3792                } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3793                        sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3794                } else {
3795                        sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3796                }
3797                // Pairwise Key Cipher Suite
3798                sFrame.pRSNWPA->wPKCount = 1;
3799                sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3800                sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3801                sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3802                if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3803                        sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3804                } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3805                        sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3806                } else {
3807                        sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3808                }
3809                // Auth Key Management Suite
3810                pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3811                *pbyRSN++ = 0x01;
3812                *pbyRSN++ = 0x00;
3813                *pbyRSN++ = 0x00;
3814
3815                *pbyRSN++ = 0x50;
3816                *pbyRSN++ = 0xf2;
3817                if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
3818                        *pbyRSN++ = WPA_AUTH_PSK;
3819                } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
3820                        *pbyRSN++ = WPA_AUTH_IEEE802_1X;
3821                } else {
3822                        *pbyRSN++ = WPA_NONE;
3823                }
3824
3825                sFrame.pRSNWPA->len += 6;
3826
3827                // RSN Capabilities
3828                *pbyRSN++ = 0x00;
3829                *pbyRSN++ = 0x00;
3830                sFrame.pRSNWPA->len += 2;
3831
3832                sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3833                // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3834                pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3835                memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3836                pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3837
3838        } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3839                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3840                   (pMgmt->pCurrBSS != NULL)) {
3841                unsigned int ii;
3842                unsigned short *pwPMKID;
3843
3844                /* WPA IE */
3845                sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3846                sFrame.pRSN->byElementID = WLAN_EID_RSN;
3847                sFrame.pRSN->len = 6; //Version(2)+GK(4)
3848                sFrame.pRSN->wVersion = 1;
3849                //Group Key Cipher Suite
3850                sFrame.pRSN->abyRSN[0] = 0x00;
3851                sFrame.pRSN->abyRSN[1] = 0x0F;
3852                sFrame.pRSN->abyRSN[2] = 0xAC;
3853                if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3854                        sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3855                } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3856                        sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3857                } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3858                        sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3859                } else {
3860                        sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3861                }
3862
3863                // Pairwise Key Cipher Suite
3864                sFrame.pRSN->abyRSN[4] = 1;
3865                sFrame.pRSN->abyRSN[5] = 0;
3866                sFrame.pRSN->abyRSN[6] = 0x00;
3867                sFrame.pRSN->abyRSN[7] = 0x0F;
3868                sFrame.pRSN->abyRSN[8] = 0xAC;
3869                if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3870                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3871                } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3872                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3873                } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
3874                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3875                } else {
3876                        sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3877                }
3878                sFrame.pRSN->len += 6;
3879
3880                // Auth Key Management Suite
3881                sFrame.pRSN->abyRSN[10] = 1;
3882                sFrame.pRSN->abyRSN[11] = 0;
3883                sFrame.pRSN->abyRSN[12] = 0x00;
3884                sFrame.pRSN->abyRSN[13] = 0x0F;
3885                sFrame.pRSN->abyRSN[14] = 0xAC;
3886                if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
3887                        sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3888                } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
3889                        sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3890                } else {
3891                        sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3892                }
3893                sFrame.pRSN->len += 6;
3894
3895                // RSN Capabilities
3896                if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) {
3897                        memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3898                } else {
3899                        sFrame.pRSN->abyRSN[16] = 0;
3900                        sFrame.pRSN->abyRSN[17] = 0;
3901                }
3902                sFrame.pRSN->len += 2;
3903
3904                if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3905                        // RSN PMKID
3906                        pbyRSN = &sFrame.pRSN->abyRSN[18];
3907                        pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
3908                        *pwPMKID = 0;            // Initialize PMKID count
3909                        pbyRSN += 2;             // Point to PMKID list
3910                        for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3911                                if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) {
3912                                        (*pwPMKID)++;
3913                                        memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
3914                                        pbyRSN += 16;
3915                                }
3916                        }
3917                        if (*pwPMKID != 0) {
3918                                sFrame.pRSN->len += (2 + (*pwPMKID) * 16);
3919                        }
3920                }
3921
3922                sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3923                // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3924                pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3925                memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
3926                pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3927        }
3928
3929        /* Adjust the length fields */
3930        pTxPacket->cbMPDULen = sFrame.len;
3931        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3932
3933        return pTxPacket;
3934}
3935
3936/*+
3937 *
3938 * Routine Description:
3939 *  Constructs an assoc-response frame
3940 *
3941 *
3942 * Return Value:
3943 *    PTR to frame; or NULL on allocation failure
3944 *
3945 -*/
3946
3947PSTxMgmtPacket
3948s_MgrMakeAssocResponse(
3949        PSDevice pDevice,
3950        PSMgmtObject pMgmt,
3951        unsigned short wCurrCapInfo,
3952        unsigned short wAssocStatus,
3953        unsigned short wAssocAID,
3954        unsigned char *pDstAddr,
3955        PWLAN_IE_SUPP_RATES pCurrSuppRates,
3956        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3957)
3958{
3959        PSTxMgmtPacket      pTxPacket = NULL;
3960        WLAN_FR_ASSOCRESP   sFrame;
3961
3962        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3963        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3964        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3965        // Setup the sFrame structure
3966        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3967        sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
3968        vMgrEncodeAssocResponse(&sFrame);
3969        // Setup the header
3970        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3971                (
3972                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3973                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
3974));
3975        memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3976        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3977        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3978
3979        *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3980        *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
3981        *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
3982
3983        // Copy the rate set
3984        sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3985        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3986        memcpy(sFrame.pSuppRates,
3987               pCurrSuppRates,
3988               ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3989);
3990
3991        if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3992                sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3993                sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3994                memcpy(sFrame.pExtSuppRates,
3995                       pCurrExtSuppRates,
3996                       ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3997);
3998        }
3999
4000        // Adjust the length fields
4001        pTxPacket->cbMPDULen = sFrame.len;
4002        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4003
4004        return pTxPacket;
4005}
4006
4007/*+
4008 *
4009 * Routine Description:
4010 *  Constructs an reassoc-response frame
4011 *
4012 *
4013 * Return Value:
4014 *    PTR to frame; or NULL on allocation failure
4015 *
4016 -*/
4017
4018PSTxMgmtPacket
4019s_MgrMakeReAssocResponse(
4020        PSDevice pDevice,
4021        PSMgmtObject pMgmt,
4022        unsigned short wCurrCapInfo,
4023        unsigned short wAssocStatus,
4024        unsigned short wAssocAID,
4025        unsigned char *pDstAddr,
4026        PWLAN_IE_SUPP_RATES pCurrSuppRates,
4027        PWLAN_IE_SUPP_RATES pCurrExtSuppRates
4028)
4029{
4030        PSTxMgmtPacket      pTxPacket = NULL;
4031        WLAN_FR_REASSOCRESP   sFrame;
4032
4033        pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
4034        memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
4035        pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
4036        // Setup the sFrame structure
4037        sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
4038        sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
4039        vMgrEncodeReassocResponse(&sFrame);
4040        // Setup the header
4041        sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
4042                (
4043                        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
4044                        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
4045));
4046        memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
4047        memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
4048        memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
4049
4050        *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
4051        *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
4052        *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
4053
4054        // Copy the rate set
4055        sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4056        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
4057        memcpy(sFrame.pSuppRates,
4058               pCurrSuppRates,
4059               ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
4060);
4061
4062        if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
4063                sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4064                sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
4065                memcpy(sFrame.pExtSuppRates,
4066                       pCurrExtSuppRates,
4067                       ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
4068);
4069        }
4070
4071        // Adjust the length fields
4072        pTxPacket->cbMPDULen = sFrame.len;
4073        pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4074
4075        return pTxPacket;
4076}
4077
4078/*+
4079 *
4080 * Routine Description:
4081 *  Handles probe response management frames.
4082 *
4083 *
4084 * Return Value:
4085 *    none.
4086 *
4087 -*/
4088
4089static
4090void
4091s_vMgrRxProbeResponse(
4092        PSDevice pDevice,
4093        PSMgmtObject pMgmt,
4094        PSRxMgmtPacket pRxPacket
4095)
4096{
4097        PKnownBSS           pBSSList = NULL;
4098        WLAN_FR_PROBERESP   sFrame;
4099        unsigned char byCurrChannel = pRxPacket->byRxChannel;
4100        ERPObject           sERP;
4101        unsigned char byIEChannel = 0;
4102        bool bChannelHit = true;
4103
4104        memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
4105        // decode the frame
4106        sFrame.len = pRxPacket->cbMPDULen;
4107        sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
4108        vMgrDecodeProbeResponse(&sFrame);
4109
4110        if ((sFrame.pqwTimestamp == 0) ||
4111            (sFrame.pwBeaconInterval == 0) ||
4112            (sFrame.pwCapInfo == 0) ||
4113            (sFrame.pSSID == 0) ||
4114            (sFrame.pSuppRates == 0)) {
4115                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
4116                DBG_PORT80(0xCC);
4117                return;
4118        }
4119
4120        if (sFrame.pSSID->len == 0)
4121                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
4122
4123        if (sFrame.pDSParms != 0) {
4124                if (byCurrChannel > CB_MAX_CHANNEL_24G) {
4125                        // channel remapping to
4126                        byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
4127                } else {
4128                        byIEChannel = sFrame.pDSParms->byCurrChannel;
4129                }
4130                if (byCurrChannel != byIEChannel) {
4131                        // adjust channel info. bcs we rcv adjacent channel packets
4132                        bChannelHit = false;
4133                        byCurrChannel = byIEChannel;
4134                }
4135        } else {
4136                // no DS channel info
4137                bChannelHit = true;
4138        }
4139
4140//2008-0730-01<Add>by MikeLiu
4141        if (ChannelExceedZoneType(pDevice, byCurrChannel))
4142                return;
4143
4144        if (sFrame.pERP != NULL) {
4145                sERP.byERP = sFrame.pERP->byContext;
4146                sERP.bERPExist = true;
4147        } else {
4148                sERP.bERPExist = false;
4149                sERP.byERP = 0;
4150        }
4151
4152        // update or insert the bss
4153        pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
4154        if (pBSSList) {
4155                BSSbUpdateToBSSList((void *)pDevice,
4156                                    *sFrame.pqwTimestamp,
4157                                    *sFrame.pwBeaconInterval,
4158                                    *sFrame.pwCapInfo,
4159                                    byCurrChannel,
4160                                    bChannelHit,
4161                                    sFrame.pSSID,
4162                                    sFrame.pSuppRates,
4163                                    sFrame.pExtSuppRates,
4164                                    &sERP,
4165                                    sFrame.pRSN,
4166                                    sFrame.pRSNWPA,
4167                                    sFrame.pIE_Country,
4168                                    sFrame.pIE_Quiet,
4169                                    pBSSList,
4170                                    sFrame.len - WLAN_HDR_ADDR3_LEN,
4171                                    sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
4172                                    (void *)pRxPacket
4173);
4174        } else {
4175                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
4176                BSSbInsertToBSSList((void *)pDevice,
4177                                    sFrame.pHdr->sA3.abyAddr3,
4178                                    *sFrame.pqwTimestamp,
4179                                    *sFrame.pwBeaconInterval,
4180                                    *sFrame.pwCapInfo,
4181                                    byCurrChannel,
4182                                    sFrame.pSSID,
4183                                    sFrame.pSuppRates,
4184                                    sFrame.pExtSuppRates,
4185                                    &sERP,
4186                                    sFrame.pRSN,
4187                                    sFrame.pRSNWPA,
4188                                    sFrame.pIE_Country,
4189                                    sFrame.pIE_Quiet,
4190                                    sFrame.len - WLAN_HDR_ADDR3_LEN,
4191                                    sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
4192                                    (void *)pRxPacket
4193);
4194        }
4195        return;
4196}
4197
4198/*+
4199 *
4200 * Routine Description:(AP)or(Ad-hoc STA)
4201 *  Handles probe request management frames.
4202 *
4203 *
4204 * Return Value:
4205 *    none.
4206 *
4207 -*/
4208
4209static
4210void
4211s_vMgrRxProbeRequest(
4212        PSDevice pDevice,
4213        PSMgmtObject pMgmt,
4214        PSRxMgmtPacket pRxPacket
4215)
4216{
4217        WLAN_FR_PROBEREQ    sFrame;
4218        CMD_STATUS          Status;
4219        PSTxMgmtPacket      pTxPacket;
4220        unsigned char byPHYType = BB_TYPE_11B;
4221
4222        // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
4223        // STA have to response this request.
4224        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
4225            ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
4226                memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
4227                // decode the frame
4228                sFrame.len = pRxPacket->cbMPDULen;
4229                sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
4230                vMgrDecodeProbeRequest(&sFrame);
4231/*
4232  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n",
4233  sFrame.pHdr->sA3.abyAddr2);
4234*/
4235                if (sFrame.pSSID->len != 0) {
4236                        if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
4237                                return;
4238                        if (memcmp(sFrame.pSSID->abySSID,
4239                                   ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
4240                                   ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
4241                                return;
4242                        }
4243                }
4244
4245                if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) {
4246                        byPHYType = BB_TYPE_11G;
4247                }
4248
4249                // Probe response reply..
4250                pTxPacket = s_MgrMakeProbeResponse
4251                        (
4252                                pDevice,
4253                                pMgmt,
4254                                pMgmt->wCurrCapInfo,
4255                                pMgmt->wCurrBeaconPeriod,
4256                                pMgmt->uCurrChannel,
4257                                0,
4258                                sFrame.pHdr->sA3.abyAddr2,
4259                                (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4260                                (unsigned char *)pMgmt->abyCurrBSSID,
4261                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4262                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
4263                                byPHYType
4264);
4265                if (pTxPacket != NULL) {
4266                        /* send the frame */
4267                        Status = csMgmt_xmit(pDevice, pTxPacket);
4268                        if (Status != CMD_STATUS_PENDING) {
4269                                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
4270                        } else {
4271//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
4272                        }
4273                }
4274        }
4275
4276        return;
4277}
4278
4279/*+
4280 *
4281 * Routine Description:
4282 *
4283 *  Entry point for the reception and handling of 802.11 management
4284 *  frames. Makes a determination of the frame type and then calls
4285 *  the appropriate function.
4286 *
4287 *
4288 * Return Value:
4289 *    none.
4290 *
4291 -*/
4292
4293void
4294vMgrRxManagePacket(
4295        void *hDeviceContext,
4296        PSMgmtObject pMgmt,
4297        PSRxMgmtPacket pRxPacket
4298)
4299{
4300        PSDevice    pDevice = (PSDevice)hDeviceContext;
4301        bool bInScan = false;
4302        unsigned int uNodeIndex = 0;
4303        NODE_STATE  eNodeState = 0;
4304        CMD_STATUS  Status;
4305
4306        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
4307                if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
4308                        eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
4309        }
4310
4311        switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) {
4312        case WLAN_FSTYPE_ASSOCREQ:
4313                // Frame Clase = 2
4314                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
4315                if (eNodeState < NODE_AUTH) {
4316                        // send deauth notification
4317                        // reason = (6) class 2 received from nonauth sta
4318                        vMgrDeAuthenBeginSta(pDevice,
4319                                             pMgmt,
4320                                             pRxPacket->p80211Header->sA3.abyAddr2,
4321                                             (6),
4322                                             &Status
4323);
4324                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
4325                } else {
4326                        s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4327                }
4328                break;
4329
4330        case WLAN_FSTYPE_ASSOCRESP:
4331                // Frame Clase = 2
4332                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
4333                s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false);
4334                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
4335                break;
4336
4337        case WLAN_FSTYPE_REASSOCREQ:
4338                // Frame Clase = 2
4339                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
4340                // Todo: reassoc
4341                if (eNodeState < NODE_AUTH) {
4342                        // send deauth notification
4343                        // reason = (6) class 2 received from nonauth sta
4344                        vMgrDeAuthenBeginSta(pDevice,
4345                                             pMgmt,
4346                                             pRxPacket->p80211Header->sA3.abyAddr2,
4347                                             (6),
4348                                             &Status
4349);
4350                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
4351
4352                }
4353                s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4354                break;
4355
4356        case WLAN_FSTYPE_REASSOCRESP:
4357                // Frame Clase = 2
4358                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
4359                s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true);
4360                break;
4361
4362        case WLAN_FSTYPE_PROBEREQ:
4363                // Frame Clase = 0
4364                //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
4365                s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
4366                break;
4367
4368        case WLAN_FSTYPE_PROBERESP:
4369                // Frame Clase = 0
4370                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
4371
4372                s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
4373                break;
4374
4375        case WLAN_FSTYPE_BEACON:
4376                // Frame Clase = 0
4377                //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
4378                if (pMgmt->eScanState != WMAC_NO_SCANNING) {
4379                        bInScan = true;
4380                }
4381                s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
4382                break;
4383
4384        case WLAN_FSTYPE_ATIM:
4385                // Frame Clase = 1
4386                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
4387                break;
4388
4389        case WLAN_FSTYPE_DISASSOC:
4390                // Frame Clase = 2
4391                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
4392                if (eNodeState < NODE_AUTH) {
4393                        // send deauth notification
4394                        // reason = (6) class 2 received from nonauth sta
4395                        vMgrDeAuthenBeginSta(pDevice,
4396                                             pMgmt,
4397                                             pRxPacket->p80211Header->sA3.abyAddr2,
4398                                             (6),
4399                                             &Status
4400);
4401                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
4402                }
4403                s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
4404                break;
4405
4406        case WLAN_FSTYPE_AUTHEN:
4407                // Frame Clase = 1
4408                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
4409                s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
4410                break;
4411
4412        case WLAN_FSTYPE_DEAUTHEN:
4413                // Frame Clase = 1
4414                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
4415                s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
4416                break;
4417
4418        default:
4419                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
4420        }
4421
4422        return;
4423}
4424
4425/*+
4426 *
4427 * Routine Description:
4428 *
4429 *
4430 *  Prepare beacon to send
4431 *
4432 * Return Value:
4433 *    true if success; false if failed.
4434 *
4435 -*/
4436bool
4437bMgrPrepareBeaconToSend(
4438        void *hDeviceContext,
4439        PSMgmtObject pMgmt
4440)
4441{
4442        PSDevice            pDevice = (PSDevice)hDeviceContext;
4443        PSTxMgmtPacket      pTxPacket;
4444
4445//    pDevice->bBeaconBufReady = false;
4446        if (pDevice->bEncryptionEnable || pDevice->bEnable8021x) {
4447                pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
4448        } else {
4449                pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
4450        }
4451        pTxPacket = s_MgrMakeBeacon
4452                (
4453                        pDevice,
4454                        pMgmt,
4455                        pMgmt->wCurrCapInfo,
4456                        pMgmt->wCurrBeaconPeriod,
4457                        pMgmt->uCurrChannel,
4458                        pMgmt->wCurrATIMWindow, //0,
4459                        (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4460                        (unsigned char *)pMgmt->abyCurrBSSID,
4461                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4462                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
4463);
4464
4465        if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
4466            (pMgmt->abyCurrBSSID[0] == 0))
4467                return false;
4468
4469        csBeacon_xmit(pDevice, pTxPacket);
4470
4471        return true;
4472}
4473
4474/*+
4475 *
4476 * Routine Description:
4477 *
4478 *  Log a warning message based on the contents of the Status
4479 *  Code field of an 802.11 management frame.  Defines are
4480 *  derived from 802.11-1997 SPEC.
4481 *
4482 * Return Value:
4483 *    none.
4484 *
4485 -*/
4486static
4487void
4488s_vMgrLogStatus(
4489        PSMgmtObject pMgmt,
4490        unsigned short wStatus
4491)
4492{
4493        switch (wStatus) {
4494        case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
4495                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
4496                break;
4497        case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
4498                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
4499                break;
4500        case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
4501                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
4502                break;
4503        case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
4504                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
4505                break;
4506        case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
4507                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
4508                break;
4509        case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
4510                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
4511                break;
4512        case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
4513                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
4514                break;
4515        case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
4516                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
4517                break;
4518        case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
4519                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
4520                break;
4521        case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
4522                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
4523                break;
4524        case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
4525                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
4526                break;
4527        case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
4528                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
4529                break;
4530        case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
4531                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
4532                break;
4533        default:
4534                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
4535                break;
4536        }
4537}
4538
4539/*
4540 *
4541 * Description:
4542 *    Add BSSID in PMKID Candidate list.
4543 *
4544 * Parameters:
4545 *  In:
4546 *      hDeviceContext - device structure point
4547 *      pbyBSSID - BSSID address for adding
4548 *      wRSNCap - BSS's RSN capability
4549 *  Out:
4550 *      none
4551 *
4552 * Return Value: none.
4553 *
4554 -*/
4555bool
4556bAdd_PMKID_Candidate(
4557        void *hDeviceContext,
4558        unsigned char *pbyBSSID,
4559        PSRSNCapObject psRSNCapObj
4560)
4561{
4562        PSDevice         pDevice = (PSDevice)hDeviceContext;
4563        PPMKID_CANDIDATE pCandidateList;
4564        unsigned int ii = 0;
4565
4566        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4567
4568        if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
4569                return false;
4570
4571        if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
4572                return false;
4573
4574        // Update Old Candidate
4575        for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
4576                pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
4577                if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
4578                        if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) {
4579                                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4580                        } else {
4581                                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4582                        }
4583                        return true;
4584                }
4585        }
4586
4587        // New Candidate
4588        pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
4589        if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) {
4590                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4591        } else {
4592                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4593        }
4594        memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
4595        pDevice->gsPMKIDCandidate.NumCandidates++;
4596        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4597        return true;
4598}
4599
4600/*
4601 *
4602 * Description:
4603 *    Flush PMKID Candidate list.
4604 *
4605 * Parameters:
4606 *  In:
4607 *      hDeviceContext - device structure point
4608 *  Out:
4609 *      none
4610 *
4611 * Return Value: none.
4612 *
4613 -*/
4614void
4615vFlush_PMKID_Candidate(
4616        void *hDeviceContext
4617)
4618{
4619        PSDevice        pDevice = (PSDevice)hDeviceContext;
4620
4621        if (pDevice == NULL)
4622                return;
4623
4624        memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
4625}
4626
4627static bool
4628s_bCipherMatch(
4629        PKnownBSS                        pBSSNode,
4630        NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
4631        unsigned char *pbyCCSPK,
4632        unsigned char *pbyCCSGK
4633)
4634{
4635        unsigned char byMulticastCipher = KEY_CTL_INVALID;
4636        unsigned char byCipherMask = 0x00;
4637        int i;
4638
4639        if (pBSSNode == NULL)
4640                return false;
4641
4642        // check cap. of BSS
4643        if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4644            (EncStatus == Ndis802_11Encryption1Enabled)) {
4645                // default is WEP only
4646                byMulticastCipher = KEY_CTL_WEP;
4647        }
4648
4649        if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4650            pBSSNode->bWPA2Valid &&
4651            //20080123-01,<Add> by Einsn Liu
4652            ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
4653                //WPA2
4654                // check Group Key Cipher
4655                if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
4656                    (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
4657                        byMulticastCipher = KEY_CTL_WEP;
4658                } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
4659                        byMulticastCipher = KEY_CTL_TKIP;
4660                } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
4661                        byMulticastCipher = KEY_CTL_CCMP;
4662                } else {
4663                        byMulticastCipher = KEY_CTL_INVALID;
4664                }
4665
4666                // check Pairwise Key Cipher
4667                for (i = 0; i < pBSSNode->wCSSPKCount; i++) {
4668                        if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
4669                            (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
4670                                // this should not happen as defined 802.11i
4671                                byCipherMask |= 0x01;
4672                        } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
4673                                byCipherMask |= 0x02;
4674                        } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
4675                                byCipherMask |= 0x04;
4676                        } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
4677                                // use group key only ignore all others
4678                                byCipherMask = 0;
4679                                i = pBSSNode->wCSSPKCount;
4680                        }
4681                }
4682
4683        } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4684                   pBSSNode->bWPAValid &&
4685                   ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
4686                //WPA
4687                // check Group Key Cipher
4688                if ((pBSSNode->byGKType == WPA_WEP40) ||
4689                    (pBSSNode->byGKType == WPA_WEP104)) {
4690                        byMulticastCipher = KEY_CTL_WEP;
4691                } else if (pBSSNode->byGKType == WPA_TKIP) {
4692                        byMulticastCipher = KEY_CTL_TKIP;
4693                } else if (pBSSNode->byGKType == WPA_AESCCMP) {
4694                        byMulticastCipher = KEY_CTL_CCMP;
4695                } else {
4696                        byMulticastCipher = KEY_CTL_INVALID;
4697                }
4698
4699                // check Pairwise Key Cipher
4700                for (i = 0; i < pBSSNode->wPKCount; i++) {
4701                        if (pBSSNode->abyPKType[i] == WPA_TKIP) {
4702                                byCipherMask |= 0x02;
4703                        } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
4704                                byCipherMask |= 0x04;
4705                        } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
4706                                // use group key only ignore all others
4707                                byCipherMask = 0;
4708                                i = pBSSNode->wPKCount;
4709                        }
4710                }
4711        }
4712
4713        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%d, %d, %d, %d, EncStatus:%d\n",
4714                byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
4715
4716        // mask our cap. with BSS
4717        if (EncStatus == Ndis802_11Encryption1Enabled) {
4718                // For supporting Cisco migration mode, don't care pairwise key cipher
4719                if ((byMulticastCipher == KEY_CTL_WEP) &&
4720                    (byCipherMask == 0)) {
4721                        *pbyCCSGK = KEY_CTL_WEP;
4722                        *pbyCCSPK = KEY_CTL_NONE;
4723                        return true;
4724                } else {
4725                        return false;
4726                }
4727
4728        } else if (EncStatus == Ndis802_11Encryption2Enabled) {
4729                if ((byMulticastCipher == KEY_CTL_TKIP) &&
4730                    (byCipherMask == 0)) {
4731                        *pbyCCSGK = KEY_CTL_TKIP;
4732                        *pbyCCSPK = KEY_CTL_NONE;
4733                        return true;
4734                } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4735                           ((byCipherMask & 0x02) != 0)) {
4736                        *pbyCCSGK = KEY_CTL_WEP;
4737                        *pbyCCSPK = KEY_CTL_TKIP;
4738                        return true;
4739                } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4740                           ((byCipherMask & 0x02) != 0)) {
4741                        *pbyCCSGK = KEY_CTL_TKIP;
4742                        *pbyCCSPK = KEY_CTL_TKIP;
4743                        return true;
4744                } else {
4745                        return false;
4746                }
4747        } else if (EncStatus == Ndis802_11Encryption3Enabled) {
4748                if ((byMulticastCipher == KEY_CTL_CCMP) &&
4749                    (byCipherMask == 0)) {
4750                        // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
4751                        return false;
4752                } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4753                           ((byCipherMask & 0x04) != 0)) {
4754                        *pbyCCSGK = KEY_CTL_WEP;
4755                        *pbyCCSPK = KEY_CTL_CCMP;
4756                        return true;
4757                } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4758                           ((byCipherMask & 0x04) != 0)) {
4759                        *pbyCCSGK = KEY_CTL_TKIP;
4760                        *pbyCCSPK = KEY_CTL_CCMP;
4761                        return true;
4762                } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
4763                           ((byCipherMask & 0x04) != 0)) {
4764                        *pbyCCSGK = KEY_CTL_CCMP;
4765                        *pbyCCSPK = KEY_CTL_CCMP;
4766                        return true;
4767                } else {
4768                        return false;
4769                }
4770        }
4771        return true;
4772}
4773