linux/drivers/staging/otus/80211core/cmmsta.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2007-2008 Atheros Communications Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include "cprecomp.h"
  18#include "ratectrl.h"
  19#include "../hal/hpreg.h"
  20
  21/* TODO : change global variable to constant */
  22u8_t   zgWpaRadiusOui[] = { 0x00, 0x50, 0xf2, 0x01 };
  23u8_t   zgWpaAesOui[] = { 0x00, 0x50, 0xf2, 0x04 };
  24u8_t   zgWpa2RadiusOui[] = { 0x00, 0x0f, 0xac, 0x01 };
  25u8_t   zgWpa2AesOui[] = { 0x00, 0x0f, 0xac, 0x04 };
  26
  27const u16_t zcCwTlb[16] = {   0,    1,    3,    7,   15,   31,   63,  127,
  28                            255,  511, 1023, 2047, 4095, 4095, 4095, 4095};
  29
  30void zfStaStartConnectCb(zdev_t* dev);
  31
  32/************************************************************************/
  33/*                                                                      */
  34/*    FUNCTION DESCRIPTION                  zfStaPutApIntoBlockingList  */
  35/*      Put AP into blocking AP list.                                   */
  36/*                                                                      */
  37/*    INPUTS                                                            */
  38/*      dev : device pointer                                            */
  39/*      bssid : AP's BSSID                                              */
  40/*      weight : weight of AP                                           */
  41/*                                                                      */
  42/*    OUTPUTS                                                           */
  43/*      none                                                            */
  44/*                                                                      */
  45/*    AUTHOR                                                            */
  46/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
  47/*                                                                      */
  48/************************************************************************/
  49void zfStaPutApIntoBlockingList(zdev_t* dev, u8_t* bssid, u8_t weight)
  50{
  51    u16_t i, j;
  52    zmw_get_wlan_dev(dev);
  53    zmw_declare_for_critical_section();
  54
  55    if (weight > 0)
  56    {
  57        zmw_enter_critical_section(dev);
  58        /*Find same bssid entry first*/
  59        for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
  60        {
  61            for (j=0; j<6; j++)
  62            {
  63                if(wd->sta.blockingApList[i].addr[j]!= bssid[j])
  64                {
  65                    break;
  66                }
  67            }
  68
  69            if(j==6)
  70            {
  71                break;
  72            }
  73        }
  74        /*This bssid doesn't have old record.Find an empty entry*/
  75        if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE)
  76        {
  77            for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
  78            {
  79                if (wd->sta.blockingApList[i].weight == 0)
  80                {
  81                    break;
  82                }
  83            }
  84        }
  85
  86        /* If the list is full, pick one entry for replacement */
  87        if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE)
  88        {
  89            i = bssid[5] & (ZM_MAX_BLOCKING_AP_LIST_SIZE-1);
  90        }
  91
  92        /* Update AP address and weight */
  93        for (j=0; j<6; j++)
  94        {
  95            wd->sta.blockingApList[i].addr[j] = bssid[j];
  96        }
  97
  98        wd->sta.blockingApList[i].weight = weight;
  99        zmw_leave_critical_section(dev);
 100    }
 101
 102    return;
 103}
 104
 105
 106/************************************************************************/
 107/*                                                                      */
 108/*    FUNCTION DESCRIPTION                  zfStaIsApInBlockingList     */
 109/*      Is AP in blocking list.                                         */
 110/*                                                                      */
 111/*    INPUTS                                                            */
 112/*      dev : device pointer                                            */
 113/*      bssid : AP's BSSID                                              */
 114/*                                                                      */
 115/*    OUTPUTS                                                           */
 116/*      TRUE : AP in blocking list                                      */
 117/*      FALSE : AP not in blocking list                                 */
 118/*                                                                      */
 119/*    AUTHOR                                                            */
 120/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
 121/*                                                                      */
 122/************************************************************************/
 123u16_t zfStaIsApInBlockingList(zdev_t* dev, u8_t* bssid)
 124{
 125    u16_t i, j;
 126    zmw_get_wlan_dev(dev);
 127    //zmw_declare_for_critical_section();
 128
 129    //zmw_enter_critical_section(dev);
 130    for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
 131    {
 132        if (wd->sta.blockingApList[i].weight != 0)
 133        {
 134            for (j=0; j<6; j++)
 135            {
 136                if (wd->sta.blockingApList[i].addr[j] != bssid[j])
 137                {
 138                    break;
 139                }
 140            }
 141            if (j == 6)
 142            {
 143                //zmw_leave_critical_section(dev);
 144                return TRUE;
 145            }
 146        }
 147    }
 148    //zmw_leave_critical_section(dev);
 149    return FALSE;
 150}
 151
 152
 153/************************************************************************/
 154/*                                                                      */
 155/*    FUNCTION DESCRIPTION                  zfStaRefreshBlockList       */
 156/*      Is AP in blocking list.                                         */
 157/*                                                                      */
 158/*    INPUTS                                                            */
 159/*      dev : device pointer                                            */
 160/*      flushFlag : flush whole blocking list                           */
 161/*                                                                      */
 162/*    OUTPUTS                                                           */
 163/*      none                                                            */
 164/*                                                                      */
 165/*    AUTHOR                                                            */
 166/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
 167/*                                                                      */
 168/************************************************************************/
 169void zfStaRefreshBlockList(zdev_t* dev, u16_t flushFlag)
 170{
 171    u16_t i;
 172    zmw_get_wlan_dev(dev);
 173    zmw_declare_for_critical_section();
 174
 175    zmw_enter_critical_section(dev);
 176    for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
 177    {
 178        if (wd->sta.blockingApList[i].weight != 0)
 179        {
 180            if (flushFlag != 0)
 181            {
 182                wd->sta.blockingApList[i].weight = 0;
 183            }
 184            else
 185            {
 186                wd->sta.blockingApList[i].weight--;
 187            }
 188        }
 189    }
 190    zmw_leave_critical_section(dev);
 191    return;
 192}
 193
 194
 195/************************************************************************/
 196/*                                                                      */
 197/*    FUNCTION DESCRIPTION                  zfStaConnectFail            */
 198/*      Handle Connect failure.                                         */
 199/*                                                                      */
 200/*    INPUTS                                                            */
 201/*      dev : device pointer                                            */
 202/*      bssid : BSSID                                                   */
 203/*      reason : reason of failure                                      */
 204/*                                                                      */
 205/*    OUTPUTS                                                           */
 206/*      none                                                            */
 207/*                                                                      */
 208/*    AUTHOR                                                            */
 209/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
 210/*                                                                      */
 211/************************************************************************/
 212void zfStaConnectFail(zdev_t* dev, u16_t reason, u16_t* bssid, u8_t weight)
 213{
 214    zmw_get_wlan_dev(dev);
 215
 216    /* Change internal state */
 217    zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
 218
 219    /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */
 220    //zfHpSetTTSIFSTime(dev, 0x8);
 221
 222    /* Notify wrapper of connection status changes */
 223    if (wd->zfcbConnectNotify != NULL)
 224    {
 225        wd->zfcbConnectNotify(dev, reason, bssid);
 226    }
 227
 228    /* Put AP into internal blocking list */
 229    zfStaPutApIntoBlockingList(dev, (u8_t *)bssid, weight);
 230
 231    /* Issue another SCAN */
 232    if ( wd->sta.bAutoReconnect )
 233    {
 234        zm_debug_msg0("Start internal scan...");
 235        zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
 236        zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
 237    }
 238}
 239
 240u8_t zfiWlanIBSSGetPeerStationsCount(zdev_t* dev)
 241{
 242    zmw_get_wlan_dev(dev);
 243
 244    return wd->sta.oppositeCount;
 245}
 246
 247u8_t zfiWlanIBSSIteratePeerStations(zdev_t* dev, u8_t numToIterate, zfpIBSSIteratePeerStationCb callback, void *ctx)
 248{
 249    u8_t oppositeCount;
 250    u8_t i;
 251    u8_t index = 0;
 252
 253    zmw_get_wlan_dev(dev);
 254
 255    zmw_declare_for_critical_section();
 256
 257    zmw_enter_critical_section(dev);
 258
 259    oppositeCount = wd->sta.oppositeCount;
 260    if ( oppositeCount > numToIterate )
 261    {
 262        oppositeCount = numToIterate;
 263    }
 264
 265    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
 266    {
 267        if ( oppositeCount == 0 )
 268        {
 269            break;
 270        }
 271
 272        if ( wd->sta.oppositeInfo[i].valid == 0 )
 273        {
 274            continue;
 275        }
 276
 277        callback(dev, &wd->sta.oppositeInfo[i], ctx, index++);
 278        oppositeCount--;
 279
 280    }
 281
 282    zmw_leave_critical_section(dev);
 283
 284    return index;
 285}
 286
 287
 288s8_t zfStaFindFreeOpposite(zdev_t* dev, u16_t *sa, int *pFoundIdx)
 289{
 290    int oppositeCount;
 291    int i;
 292
 293    zmw_get_wlan_dev(dev);
 294
 295    oppositeCount = wd->sta.oppositeCount;
 296
 297    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
 298    {
 299        if ( oppositeCount == 0 )
 300        {
 301            break;
 302        }
 303
 304        if ( wd->sta.oppositeInfo[i].valid == 0 )
 305        {
 306            continue;
 307        }
 308
 309        oppositeCount--;
 310        if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) )
 311        {
 312            //wd->sta.oppositeInfo[i].aliveCounter++;
 313            wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
 314
 315            /* it is already stored */
 316            return 1;
 317        }
 318    }
 319
 320    // Check if there's still space for new comer
 321    if ( wd->sta.oppositeCount == ZM_MAX_OPPOSITE_COUNT )
 322    {
 323        return -1;
 324    }
 325
 326    // Find an unused slot for new peer station
 327    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
 328    {
 329        if ( wd->sta.oppositeInfo[i].valid == 0 )
 330        {
 331            break;
 332        }
 333    }
 334
 335    *pFoundIdx = i;
 336    return 0;
 337}
 338
 339s8_t zfStaFindOppositeByMACAddr(zdev_t* dev, u16_t *sa, u8_t *pFoundIdx)
 340{
 341    u32_t oppositeCount;
 342    u32_t i;
 343
 344    zmw_get_wlan_dev(dev);
 345
 346    oppositeCount = wd->sta.oppositeCount;
 347
 348    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
 349    {
 350        if ( oppositeCount == 0 )
 351        {
 352            break;
 353        }
 354
 355        if ( wd->sta.oppositeInfo[i].valid == 0 )
 356        {
 357            continue;
 358        }
 359
 360        oppositeCount--;
 361        if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) )
 362        {
 363            *pFoundIdx = (u8_t)i;
 364
 365            return 0;
 366        }
 367    }
 368
 369    *pFoundIdx = 0;
 370    return 1;
 371}
 372
 373static void zfStaInitCommonOppositeInfo(zdev_t* dev, int i)
 374{
 375    zmw_get_wlan_dev(dev);
 376
 377    /* set the default rate to the highest rate */
 378    wd->sta.oppositeInfo[i].valid = 1;
 379    wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
 380    wd->sta.oppositeCount++;
 381
 382#ifdef ZM_ENABLE_IBSS_WPA2PSK
 383    /* Set parameters for new opposite peer station !!! */
 384    wd->sta.oppositeInfo[i].camIdx = 0xff;  // Not set key in this location
 385    wd->sta.oppositeInfo[i].pkInstalled = 0;
 386    wd->sta.oppositeInfo[i].wpaState = ZM_STA_WPA_STATE_INIT ;  // No encryption
 387#endif
 388}
 389
 390int zfStaSetOppositeInfoFromBSSInfo(zdev_t* dev, struct zsBssInfo* pBssInfo)
 391{
 392    int i;
 393    u8_t*  dst;
 394    u16_t  sa[3];
 395    int res;
 396    u32_t oneTxStreamCap;
 397
 398    zmw_get_wlan_dev(dev);
 399
 400    zfMemoryCopy((u8_t*) sa, pBssInfo->macaddr, 6);
 401
 402    res = zfStaFindFreeOpposite(dev, sa, &i);
 403    if ( res != 0 )
 404    {
 405        goto zlReturn;
 406    }
 407
 408    dst = wd->sta.oppositeInfo[i].macAddr;
 409    zfMemoryCopy(dst, (u8_t *)sa, 6);
 410
 411    oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
 412
 413    if (pBssInfo->extSupportedRates[1] != 0)
 414    {
 415        /* TODO : Handle 11n */
 416        if (pBssInfo->frequency < 3000)
 417        {
 418            /* 2.4GHz */
 419            if (pBssInfo->EnableHT == 1)
 420                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40);
 421            else
 422                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, pBssInfo->SG40);
 423        }
 424        else
 425        {
 426            /* 5GHz */
 427            if (pBssInfo->EnableHT == 1)
 428                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40);
 429            else
 430                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40);
 431        }
 432    }
 433    else
 434    {
 435        /* TODO : Handle 11n */
 436        if (pBssInfo->frequency < 3000)
 437        {
 438            /* 2.4GHz */
 439            if (pBssInfo->EnableHT == 1)
 440                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40);
 441            else
 442                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, pBssInfo->SG40);
 443        }
 444        else
 445        {
 446            /* 5GHz */
 447            if (pBssInfo->EnableHT == 1)
 448                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40);
 449            else
 450                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40);
 451        }
 452    }
 453
 454
 455    zfStaInitCommonOppositeInfo(dev, i);
 456zlReturn:
 457    return 0;
 458}
 459
 460int zfStaSetOppositeInfoFromRxBuf(zdev_t* dev, zbuf_t* buf)
 461{
 462    int   i;
 463    u8_t*  dst;
 464    u16_t  sa[3];
 465    int res = 0;
 466    u16_t  offset;
 467    u8_t   bSupportExtRate;
 468    u32_t rtsctsRate = 0xffffffff; /* CTS:OFDM 6M, RTS:OFDM 6M */
 469    u32_t oneTxStreamCap;
 470
 471    zmw_get_wlan_dev(dev);
 472    zmw_declare_for_critical_section();
 473
 474    sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
 475    sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2);
 476    sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4);
 477
 478    zmw_enter_critical_section(dev);
 479
 480    res = zfStaFindFreeOpposite(dev, sa, &i);
 481    if ( res != 0 )
 482    {
 483        goto zlReturn;
 484    }
 485
 486    dst = wd->sta.oppositeInfo[i].macAddr;
 487    zfCopyFromRxBuffer(dev, buf, dst, ZM_WLAN_HEADER_A2_OFFSET, 6);
 488
 489    if ( (wd->sta.currentFrequency < 3000) && !(wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
 490    {
 491        bSupportExtRate = 0;
 492    } else {
 493        bSupportExtRate = 1;
 494    }
 495
 496    if ( (bSupportExtRate == 1)
 497         && (wd->sta.currentFrequency < 3000)
 498         && (wd->wlanMode == ZM_MODE_IBSS)
 499         && (wd->wfc.bIbssGMode == 0) )
 500    {
 501        bSupportExtRate = 0;
 502    }
 503
 504    wd->sta.connection_11b = 0;
 505    oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
 506
 507    if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff)
 508         && (bSupportExtRate == 1) )
 509    {
 510        /* TODO : Handle 11n */
 511        if (wd->sta.currentFrequency < 3000)
 512        {
 513            /* 2.4GHz */
 514            if (wd->sta.EnableHT == 1)
 515            {
 516                //11ng
 517                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40);
 518            }
 519            else
 520            {
 521                //11g
 522                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, wd->sta.SG40);
 523            }
 524            rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */
 525        }
 526        else
 527        {
 528            /* 5GHz */
 529            if (wd->sta.EnableHT == 1)
 530            {
 531                //11na
 532                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40);
 533            }
 534            else
 535            {
 536                //11a
 537                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40);
 538            }
 539            rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */
 540        }
 541    }
 542    else
 543    {
 544        /* TODO : Handle 11n */
 545        if (wd->sta.currentFrequency < 3000)
 546        {
 547            /* 2.4GHz */
 548            if (wd->sta.EnableHT == 1)
 549            {
 550                //11ng
 551                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40);
 552                rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */
 553            }
 554            else
 555            {
 556                //11b
 557                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, wd->sta.SG40);
 558                rtsctsRate = 0x0; /* CTS:CCK 1M, RTS:CCK 1M */
 559                wd->sta.connection_11b = 1;
 560            }
 561        }
 562        else
 563        {
 564            /* 5GHz */
 565            if (wd->sta.EnableHT == 1)
 566            {
 567                //11na
 568                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40);
 569            }
 570            else
 571            {
 572                //11a
 573                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40);
 574            }
 575            rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */
 576        }
 577    }
 578
 579    zfStaInitCommonOppositeInfo(dev, i);
 580
 581zlReturn:
 582    zmw_leave_critical_section(dev);
 583
 584    if (rtsctsRate != 0xffffffff)
 585    {
 586        zfHpSetRTSCTSRate(dev, rtsctsRate);
 587    }
 588    return res;
 589}
 590
 591void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf)
 592{
 593    u16_t   offset;
 594    u8_t    erp;
 595    u8_t    bssid[6];
 596
 597    zmw_get_wlan_dev(dev);
 598
 599    if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&(zfStaIsConnected(dev)) )
 600    {
 601        ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid);
 602
 603        if (zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6))
 604        {
 605            if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff )
 606            {
 607                erp = zmw_rx_buf_readb(dev, buf, offset+2);
 608
 609                if ( erp & ZM_BIT_1 )
 610                {
 611                    //zm_debug_msg0("protection mode on");
 612                    if (wd->sta.bProtectionMode == FALSE)
 613                    {
 614                        wd->sta.bProtectionMode = TRUE;
 615                        zfHpSetSlotTime(dev, 0);
 616                    }
 617                }
 618                else
 619                {
 620                    //zm_debug_msg0("protection mode off");
 621                    if (wd->sta.bProtectionMode == TRUE)
 622                    {
 623                        wd->sta.bProtectionMode = FALSE;
 624                        zfHpSetSlotTime(dev, 1);
 625                    }
 626                }
 627            }
 628        }
 629                //Check the existence of Non-N AP
 630                //Follow the check the "pBssInfo->EnableHT"
 631                        if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff)
 632                        {}
 633                        else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
 634                        {}
 635                        else
 636                        {wd->sta.NonNAPcount++;}
 637    }
 638}
 639
 640void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf)
 641{
 642    u16_t   tmp;
 643    u16_t   aifs[5];
 644    u16_t   cwmin[5];
 645    u16_t   cwmax[5];
 646    u16_t   txop[5];
 647    u8_t    acm;
 648    u8_t    ac;
 649    u16_t   len;
 650    u16_t   i;
 651        u16_t   offset;
 652    u8_t    rxWmeParameterSetCount;
 653
 654    zmw_get_wlan_dev(dev);
 655
 656    /* Update if WME parameter set count is changed */
 657    /* If connect to WME AP */
 658    if (wd->sta.wmeConnected != 0)
 659    {
 660        /* Find WME parameter element */
 661        if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff)
 662        {
 663            if ((len = zmw_rx_buf_readb(dev, buf, offset+1)) >= 7)
 664            {
 665                rxWmeParameterSetCount=zmw_rx_buf_readb(dev, buf, offset+8);
 666                if (rxWmeParameterSetCount != wd->sta.wmeParameterSetCount)
 667                {
 668                    zm_msg0_mm(ZM_LV_0, "wmeParameterSetCount changed!");
 669                    wd->sta.wmeParameterSetCount = rxWmeParameterSetCount;
 670                    /* retrieve WME parameter and update TxQ parameters */
 671                    acm = 0xf;
 672                    for (i=0; i<4; i++)
 673                    {
 674                        if (len >= (8+(i*4)+4))
 675                        {
 676                            tmp=zmw_rx_buf_readb(dev, buf, offset+10+i*4);
 677                            ac = (tmp >> 5) & 0x3;
 678                            if ((tmp & 0x10) == 0)
 679                            {
 680                                acm &= (~(1<<ac));
 681                            }
 682                            aifs[ac] = ((tmp & 0xf) * 9) + 10;
 683                            tmp=zmw_rx_buf_readb(dev, buf, offset+11+i*4);
 684                            /* Convert to 2^n */
 685                            cwmin[ac] = zcCwTlb[(tmp & 0xf)];
 686                            cwmax[ac] = zcCwTlb[(tmp >> 4)];
 687                            txop[ac]=zmw_rx_buf_readh(dev, buf,
 688                                    offset+12+i*4);
 689                        }
 690                    }
 691
 692                    if ((acm & 0x4) != 0)
 693                    {
 694                        cwmin[2] = cwmin[0];
 695                        cwmax[2] = cwmax[0];
 696                        aifs[2] = aifs[0];
 697                        txop[2] = txop[0];
 698                    }
 699                    if ((acm & 0x8) != 0)
 700                    {
 701                        cwmin[3] = cwmin[2];
 702                        cwmax[3] = cwmax[2];
 703                        aifs[3] = aifs[2];
 704                        txop[3] = txop[2];
 705                    }
 706                    cwmin[4] = 3;
 707                    cwmax[4] = 7;
 708                    aifs[4] = 28;
 709
 710                    if ((cwmin[2]+aifs[2]) > ((cwmin[0]+aifs[0])+1))
 711                    {
 712                        wd->sta.ac0PriorityHigherThanAc2 = 1;
 713                    }
 714                    else
 715                    {
 716                        wd->sta.ac0PriorityHigherThanAc2 = 0;
 717                    }
 718                    zfHpUpdateQosParameter(dev, cwmin, cwmax, aifs, txop);
 719                }
 720            }
 721        }
 722    } //if (wd->sta.wmeConnected != 0)
 723}
 724/* process 802.11h Dynamic Frequency Selection */
 725void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
 726{
 727    //u8_t    length, channel, is5G;
 728    u16_t   offset;
 729
 730    zmw_get_wlan_dev(dev);
 731
 732    /*
 733    Channel Switch Announcement Element Format
 734    +------+----------+------+-------------------+------------------+--------------------+
 735    |Format|Element ID|Length|Channel Switch Mode|New Channel Number|Channel Switch Count|
 736    +------+----------+------+-------------------+------------------+--------------------+
 737    |Bytes |   1      |  1   |       1           |       1          |          1         |
 738    +------+----------+------+-------------------+------------------+--------------------+
 739    |Value |   37     |  3   |       0 or 1      |unsigned integer  |unsigned integer    |
 740    +------+----------+------+-------------------+------------------+--------------------+
 741    */
 742
 743    /* get EID(Channel Switch Announcement) */
 744    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE)) == 0xffff )
 745    {
 746        //zm_debug_msg0("EID(Channel Switch Announcement) not found");
 747        return;
 748    }
 749    else if ( zmw_rx_buf_readb(dev, buf, offset+1) == 0x3 )
 750    {
 751        zm_debug_msg0("EID(Channel Switch Announcement) found");
 752
 753        //length = zmw_rx_buf_readb(dev, buf, offset+1);
 754        //zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2);
 755
 756        //Chanell Switch Mode set to 1, driver should disable transmit immediate
 757        //we do this by poll CCA high
 758        if (zmw_rx_buf_readb(dev, buf, offset+2) == 0x1 )
 759        {
 760                //use ZM_OID_INTERNAL_WRITE,ZM_CMD_RESET to notice firmware flush quene and stop dma,
 761                //then restart rx dma but not tx dma
 762                if (wd->sta.DFSDisableTx != TRUE)
 763                {
 764                /* TODO : zfHpResetTxRx would cause Rx hang */
 765                //zfHpResetTxRx(dev);
 766                wd->sta.DFSDisableTx = TRUE;
 767                /* Trgger Rx DMA */
 768                zfHpStartRecv(dev);
 769            }
 770                //Adapter->ZD80211HSetting.DisableTxBy80211H=TRUE;
 771                //AcquireCtrOfPhyReg(Adapter);
 772                //ZD1205_WRITE_REGISTER(Adapter,CR24, 0x0);
 773                //ReleaseDoNotSleep(Adapter);
 774        }
 775
 776        if (zmw_rx_buf_readb(dev, buf, offset+4) <= 0x2 )
 777        {
 778                //Channel Switch
 779                //if Channel Switch Count = 0 , STA should change channel immediately.
 780                //if Channel Switch Count > 0 , STA should change channel after TBTT*count
 781                //But it won't be accurate to let driver calculate TBTT*count, and the value of
 782                //Channel Switch Count will decrease by one each when continue receving beacon
 783                //So we change channel here when we receive count <=2.
 784
 785            zfHpDeleteAllowChannel(dev, wd->sta.currentFrequency);
 786                wd->frequency = zfChNumToFreq(dev, zmw_rx_buf_readb(dev, buf, offset+3), 0);
 787                //zfHpAddAllowChannel(dev, wd->frequency);
 788                zm_debug_msg1("CWY - jump to frequency = ", wd->frequency);
 789                zfCoreSetFrequency(dev, wd->frequency);
 790                wd->sta.DFSDisableTx = FALSE;
 791            /* Increase rxBeaconCount to prevent beacon lost */
 792            if (zfStaIsConnected(dev))
 793            {
 794                wd->sta.rxBeaconCount = 1 << 6; // 2 times of check would pass
 795            }
 796                //start tx dma to transmit packet
 797
 798                //if (zmw_rx_buf_readb(dev, buf, offset+3) != wd->frequency)
 799                //{
 800                //      //ZDDbgPrint(("Radar Detect by AP\n"));
 801                //      zfCoreSetFrequency();
 802                //      ProcessRadarDetectEvent(Adapter);
 803                //      Set_RF_Channel(Adapter, SwRfd->Rfd->RxBuffer[index+3], (UCHAR)Adapter->RF_Mode, 1);
 804                //      Adapter->CardSetting.Channel = SwRfd->Rfd->RxBuffer[index+3];
 805                //      Adapter->SaveChannel = Adapter->CardSetting.Channel;
 806                //      Adapter->UtilityChannel = Adapter->CardSetting.Channel;
 807                //}
 808        }
 809    }
 810
 811}
 812/* TODO : process 802.11h Transmission Power Control */
 813void zfStaUpdateDot11HTPC(zdev_t* dev, zbuf_t* buf)
 814{
 815}
 816
 817/* IBSS power-saving mode */
 818void zfStaIbssPSCheckState(zdev_t* dev, zbuf_t* buf)
 819{
 820    u8_t   i, frameCtrl;
 821
 822    zmw_get_wlan_dev(dev);
 823
 824    if ( !zfStaIsConnected(dev) )
 825    {
 826        return;
 827    }
 828
 829    if ( wd->wlanMode != ZM_MODE_IBSS )
 830    {
 831        return ;
 832    }
 833
 834    /* check BSSID */
 835    if ( !zfRxBufferEqualToStr(dev, buf, (u8_t*) wd->sta.bssid,
 836                               ZM_WLAN_HEADER_A3_OFFSET, 6) )
 837    {
 838        return;
 839    }
 840
 841    frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
 842
 843    /* check power management bit */
 844    if ( frameCtrl & ZM_BIT_4 )
 845    {
 846        for(i=1; i<ZM_MAX_PS_STA; i++)
 847        {
 848            if ( !wd->sta.staPSList.entity[i].bUsed )
 849            {
 850                continue;
 851            }
 852
 853            /* check source address */
 854            if ( zfRxBufferEqualToStr(dev, buf,
 855                                      wd->sta.staPSList.entity[i].macAddr,
 856                                      ZM_WLAN_HEADER_A2_OFFSET, 6) )
 857            {
 858                return;
 859            }
 860        }
 861
 862        for(i=1; i<ZM_MAX_PS_STA; i++)
 863        {
 864            if ( !wd->sta.staPSList.entity[i].bUsed )
 865            {
 866                wd->sta.staPSList.entity[i].bUsed = TRUE;
 867                wd->sta.staPSList.entity[i].bDataQueued = FALSE;
 868                break;
 869            }
 870        }
 871
 872        if ( i == ZM_MAX_PS_STA )
 873        {
 874            /* STA list is full */
 875            return;
 876        }
 877
 878        zfCopyFromRxBuffer(dev, buf, wd->sta.staPSList.entity[i].macAddr,
 879                           ZM_WLAN_HEADER_A2_OFFSET, 6);
 880
 881        if ( wd->sta.staPSList.count == 0 )
 882        {
 883            // enable ATIM window
 884            //zfEnableAtimWindow(dev);
 885        }
 886
 887        wd->sta.staPSList.count++;
 888    }
 889    else if ( wd->sta.staPSList.count )
 890    {
 891        for(i=1; i<ZM_MAX_PS_STA; i++)
 892        {
 893            if ( wd->sta.staPSList.entity[i].bUsed )
 894            {
 895                if ( zfRxBufferEqualToStr(dev, buf,
 896                                          wd->sta.staPSList.entity[i].macAddr,
 897                                          ZM_WLAN_HEADER_A2_OFFSET, 6) )
 898                {
 899                    wd->sta.staPSList.entity[i].bUsed = FALSE;
 900                    wd->sta.staPSList.count--;
 901
 902                    if ( wd->sta.staPSList.entity[i].bDataQueued )
 903                    {
 904                        /* send queued data */
 905                    }
 906                }
 907            }
 908        }
 909
 910        if ( wd->sta.staPSList.count == 0 )
 911        {
 912            /* disable ATIM window */
 913            //zfDisableAtimWindow(dev);
 914        }
 915
 916    }
 917}
 918
 919/* IBSS power-saving mode */
 920u8_t zfStaIbssPSQueueData(zdev_t* dev, zbuf_t* buf)
 921{
 922    u8_t   i;
 923    u16_t  da[3];
 924
 925    zmw_get_wlan_dev(dev);
 926
 927    if ( !zfStaIsConnected(dev) )
 928    {
 929        return 0;
 930    }
 931
 932    if ( wd->wlanMode != ZM_MODE_IBSS )
 933    {
 934        return 0;
 935    }
 936
 937    if ( wd->sta.staPSList.count == 0 && wd->sta.powerSaveMode <= ZM_STA_PS_NONE )
 938    {
 939        return 0;
 940    }
 941
 942    /* DA */
 943#ifdef ZM_ENABLE_NATIVE_WIFI
 944    da[0] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
 945    da[1] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 2);
 946    da[2] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 4);
 947#else
 948    da[0] = zmw_tx_buf_readh(dev, buf, 0);
 949    da[1] = zmw_tx_buf_readh(dev, buf, 2);
 950    da[2] = zmw_tx_buf_readh(dev, buf, 4);
 951#endif
 952
 953    if ( ZM_IS_MULTICAST_OR_BROADCAST(da) )
 954    {
 955        wd->sta.staPSList.entity[0].bDataQueued = TRUE;
 956        wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf;
 957        return 1;
 958    }
 959
 960    // Unicast packet...
 961
 962    for(i=1; i<ZM_MAX_PS_STA; i++)
 963    {
 964        if ( zfMemoryIsEqual(wd->sta.staPSList.entity[i].macAddr,
 965                             (u8_t*) da, 6) )
 966        {
 967            wd->sta.staPSList.entity[i].bDataQueued = TRUE;
 968            wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf;
 969
 970            return 1;
 971        }
 972    }
 973
 974#if 0
 975    if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
 976    {
 977        wd->sta.staPSDataQueue[wd->sta.staPSDataCount++] = buf;
 978
 979        return 1;
 980    }
 981#endif
 982
 983    return 0;
 984}
 985
 986/* IBSS power-saving mode */
 987void zfStaIbssPSSend(zdev_t* dev)
 988{
 989    u8_t   i;
 990    u16_t  bcastAddr[3] = {0xffff, 0xffff, 0xffff};
 991
 992    zmw_get_wlan_dev(dev);
 993
 994    if ( !zfStaIsConnected(dev) )
 995    {
 996        return ;
 997    }
 998
 999    if ( wd->wlanMode != ZM_MODE_IBSS )
1000    {
1001        return ;
1002    }
1003
1004    for(i=0; i<ZM_MAX_PS_STA; i++)
1005    {
1006        if ( wd->sta.staPSList.entity[i].bDataQueued )
1007        {
1008            if ( i == 0 )
1009            {
1010                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM,
1011                              bcastAddr,
1012                              0, 0, 0);
1013            }
1014            else if ( wd->sta.staPSList.entity[i].bUsed )
1015            {
1016                // Send ATIM to prevent the peer to go to sleep
1017                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM,
1018                              (u16_t*) wd->sta.staPSList.entity[i].macAddr,
1019                              0, 0, 0);
1020            }
1021
1022            wd->sta.staPSList.entity[i].bDataQueued = FALSE;
1023        }
1024    }
1025
1026    for(i=0; i<wd->sta.ibssPSDataCount; i++)
1027    {
1028        zfTxSendEth(dev, wd->sta.ibssPSDataQueue[i], 0,
1029                    ZM_EXTERNAL_ALLOC_BUF, 0);
1030    }
1031
1032    wd->sta.ibssPrevPSDataCount = wd->sta.ibssPSDataCount;
1033    wd->sta.ibssPSDataCount = 0;
1034}
1035
1036
1037void zfStaReconnect(zdev_t* dev)
1038{
1039    zmw_get_wlan_dev(dev);
1040    zmw_declare_for_critical_section();
1041
1042    if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE &&
1043         wd->wlanMode != ZM_MODE_IBSS )
1044    {
1045        return;
1046    }
1047
1048    if ( (zfStaIsConnected(dev))||(zfStaIsConnecting(dev)) )
1049    {
1050        return;
1051    }
1052
1053    if ( wd->sta.bChannelScan )
1054    {
1055        return;
1056    }
1057
1058    /* Recover zero SSID length  */
1059    if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (wd->ws.ssidLen == 0))
1060    {
1061        zm_debug_msg0("zfStaReconnect: NOT Support!! Set SSID to any BSS");
1062        /* ANY BSS */
1063        zmw_enter_critical_section(dev);
1064        wd->sta.ssid[0] = 0;
1065        wd->sta.ssidLen = 0;
1066        zmw_leave_critical_section(dev);
1067    }
1068
1069    // RAY: To ensure no TX pending before re-connecting
1070    zfFlushVtxq(dev);
1071    zfWlanEnable(dev);
1072    zfScanMgrScanAck(dev);
1073}
1074
1075void zfStaTimer100ms(zdev_t* dev)
1076{
1077    zmw_get_wlan_dev(dev);
1078
1079    if ( (wd->tick % 10) == 0 )
1080    {
1081        zfPushVtxq(dev);
1082//        zfPowerSavingMgrMain(dev);
1083    }
1084}
1085
1086
1087void zfStaCheckRxBeacon(zdev_t* dev)
1088{
1089    zmw_get_wlan_dev(dev);
1090
1091    if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) && (zfStaIsConnected(dev)))
1092    {
1093        if (wd->beaconInterval == 0)
1094        {
1095            wd->beaconInterval = 100;
1096        }
1097        if ( (wd->tick % ((wd->beaconInterval * 10) / ZM_MS_PER_TICK)) == 0 )
1098        {
1099            /* Check rxBeaconCount */
1100            if (wd->sta.rxBeaconCount == 0)
1101            {
1102                if (wd->sta.beaconMissState == 1)
1103                {
1104                /*notify AP that we left*/
1105                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0);
1106                /* Beacon Lost */
1107                zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS,
1108                        wd->sta.bssid, 0);
1109                }
1110                else
1111                {
1112                    wd->sta.beaconMissState = 1;
1113                    /* Reset channel */
1114                    zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40,
1115                            wd->ExtOffset, NULL, 1);
1116                }
1117            }
1118            else
1119            {
1120                wd->sta.beaconMissState = 0;
1121            }
1122            wd->sta.rxBeaconCount = 0;
1123        }
1124    }
1125}
1126
1127
1128
1129void zfStaCheckConnectTimeout(zdev_t* dev)
1130{
1131    zmw_get_wlan_dev(dev);
1132    zmw_declare_for_critical_section();
1133
1134    if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
1135    {
1136        return;
1137    }
1138
1139    if ( !zfStaIsConnecting(dev) )
1140    {
1141        return;
1142    }
1143
1144    zmw_enter_critical_section(dev);
1145    if ( (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN)||
1146         (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1)||
1147         (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2)||
1148         (wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE) )
1149    {
1150        if ( (wd->tick - wd->sta.connectTimer) > ZM_INTERVAL_CONNECT_TIMEOUT )
1151        {
1152            if ( wd->sta.connectByReasso )
1153            {
1154                wd->sta.failCntOfReasso++;
1155                if ( wd->sta.failCntOfReasso > 2 )
1156                {
1157                    wd->sta.connectByReasso = FALSE;
1158                }
1159            }
1160
1161            wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
1162            zm_debug_msg1("connect timeout, state = ", wd->sta.connectState);
1163            //zfiWlanDisable(dev);
1164            goto failed;
1165        }
1166    }
1167
1168    zmw_leave_critical_section(dev);
1169    return;
1170
1171failed:
1172    zmw_leave_critical_section(dev);
1173    if(wd->sta.authMode == ZM_AUTH_MODE_AUTO)
1174        { // Fix some AP not send authentication failed message to sta and lead to connect timeout !
1175            wd->sta.connectTimeoutCount++;
1176        }
1177    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT, wd->sta.bssid, 2);
1178    return;
1179}
1180
1181void zfMmStaTimeTick(zdev_t* dev)
1182{
1183    zmw_get_wlan_dev(dev);
1184
1185    /* airopeek */
1186    if (wd->wlanMode != ZM_MODE_AP && !wd->swSniffer)
1187    {
1188        if ( wd->tick & 1 )
1189        {
1190            zfTimerCheckAndHandle(dev);
1191        }
1192
1193        zfStaCheckRxBeacon(dev);
1194        zfStaTimer100ms(dev);
1195        zfStaCheckConnectTimeout(dev);
1196        zfPowerSavingMgrMain(dev);
1197    }
1198
1199#ifdef ZM_ENABLE_AGGREGATION
1200    /*
1201     * add by honda
1202     */
1203    zfAggScanAndClear(dev, wd->tick);
1204#endif
1205}
1206
1207void zfStaSendBeacon(zdev_t* dev)
1208{
1209    zbuf_t* buf;
1210    u16_t offset, seq;
1211
1212    zmw_get_wlan_dev(dev);
1213
1214    zmw_declare_for_critical_section();
1215
1216    //zm_debug_msg0("\n");
1217
1218    /* TBD : Maximum size of beacon */
1219    if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
1220    {
1221        zm_debug_msg0("Allocate beacon buffer failed");
1222        return;
1223    }
1224
1225    offset = 0;
1226    /* wlan header */
1227    /* Frame control */
1228    zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1229    offset+=2;
1230    /* Duration */
1231    zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1232    offset+=2;
1233    /* Address 1 */
1234    zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1235    offset+=2;
1236    zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1237    offset+=2;
1238    zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1239    offset+=2;
1240    /* Address 2 */
1241    zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1242    offset+=2;
1243    zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1244    offset+=2;
1245    zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]);
1246    offset+=2;
1247    /* Address 3 */
1248    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[0]);
1249    offset+=2;
1250    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[1]);
1251    offset+=2;
1252    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[2]);
1253    offset+=2;
1254
1255    /* Sequence number */
1256    zmw_enter_critical_section(dev);
1257    seq = ((wd->mmseq++)<<4);
1258    zmw_leave_critical_section(dev);
1259    zmw_tx_buf_writeh(dev, buf, offset, seq);
1260    offset+=2;
1261
1262    /* 24-31 Time Stamp : hardware will fill this field */
1263    offset+=8;
1264
1265    /* Beacon Interval */
1266    zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1267    offset+=2;
1268
1269    /* Capability */
1270    zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]);
1271    zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]);
1272
1273    /* SSID */
1274    offset = zfStaAddIeSsid(dev, buf, offset);
1275
1276    if(wd->frequency <= ZM_CH_G_14)  // 2.4 GHz  b+g
1277    {
1278
1279        /* Support Rate */
1280        offset = zfMmAddIeSupportRate(dev, buf, offset,
1281                                                ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
1282
1283        /* DS parameter set */
1284        offset = zfMmAddIeDs(dev, buf, offset);
1285
1286        offset = zfStaAddIeIbss(dev, buf, offset);
1287
1288        if( wd->wfc.bIbssGMode
1289            && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )    // Only accompany with enabling a mode .
1290        {
1291            /* ERP Information */
1292            wd->erpElement = 0;
1293            offset = zfMmAddIeErp(dev, buf, offset);
1294        }
1295
1296        /* TODO : country information */
1297        /* RSN */
1298        if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
1299        {
1300            offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH);
1301        }
1302
1303        if( wd->wfc.bIbssGMode
1304            && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )    // Only accompany with enabling a mode .
1305        {
1306            /* Enable G Mode */
1307            /* Extended Supported Rates */
1308            offset = zfMmAddIeSupportRate(dev, buf, offset,
1309                                                    ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
1310            }
1311    }
1312    else    // 5GHz a
1313    {
1314        /* Support Rate a Mode */
1315        offset = zfMmAddIeSupportRate(dev, buf, offset,
1316                                            ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
1317
1318        /* DS parameter set */
1319        offset = zfMmAddIeDs(dev, buf, offset);
1320
1321        offset = zfStaAddIeIbss(dev, buf, offset);
1322
1323        /* TODO : country information */
1324        /* RSN */
1325        if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
1326        {
1327            offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH);
1328        }
1329    }
1330
1331    if ( wd->wlanMode != ZM_MODE_IBSS )
1332    {
1333        /* TODO : Need to check if it is ok */
1334        /* HT Capabilities Info */
1335        offset = zfMmAddHTCapability(dev, buf, offset);
1336
1337        /* Extended HT Capabilities Info */
1338        offset = zfMmAddExtendedHTCapability(dev, buf, offset);
1339    }
1340
1341    if ( wd->sta.ibssAdditionalIESize )
1342        offset = zfStaAddIbssAdditionalIE(dev, buf, offset);
1343
1344    /* 1212 : write to beacon fifo */
1345    /* 1221 : write to share memory */
1346    zfHpSendBeacon(dev, buf, offset);
1347
1348    /* Free beacon buffer */
1349    //zfwBufFree(dev, buf, 0);
1350}
1351
1352void zfStaSignalStatistic(zdev_t* dev, u8_t SignalStrength, u8_t SignalQuality) //CWYang(+)
1353{
1354    zmw_get_wlan_dev(dev);
1355
1356    /* Add Your Code to Do Works Like Moving Average Here */
1357    wd->SignalStrength = (wd->SignalStrength * 7 + SignalStrength * 3)/10;
1358    wd->SignalQuality = (wd->SignalQuality * 7 + SignalQuality * 3)/10;
1359
1360}
1361
1362struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeRspFrameHeader *pProbeRspHeader)
1363{
1364    u8_t    i;
1365    u8_t    j;
1366    u8_t    k;
1367    u8_t    isMatched, length, channel;
1368    u16_t   offset, frequency;
1369    struct zsBssInfo* pBssInfo;
1370
1371    zmw_get_wlan_dev(dev);
1372
1373    if ((pBssInfo = wd->sta.bssList.head) == NULL)
1374    {
1375        return NULL;
1376    }
1377
1378    for( i=0; i<wd->sta.bssList.bssCount; i++ )
1379    {
1380        //zm_debug_msg2("check pBssInfo = ", pBssInfo);
1381
1382        /* Check BSSID */
1383        for( j=0; j<6; j++ )
1384        {
1385            if ( pBssInfo->bssid[j] != pProbeRspHeader->bssid[j] )
1386            {
1387                break;
1388            }
1389        }
1390
1391                /* Check SSID */
1392        if (j == 6)
1393        {
1394            if (pProbeRspHeader->ssid[1] <= 32)
1395            {
1396                /* compare length and ssid */
1397                isMatched = 1;
1398                                if((pProbeRspHeader->ssid[1] != 0) && (pBssInfo->ssid[1] != 0))
1399                                {
1400                for( k=1; k<pProbeRspHeader->ssid[1] + 1; k++ )
1401                {
1402                    if ( pBssInfo->ssid[k] != pProbeRspHeader->ssid[k] )
1403                    {
1404                        isMatched = 0;
1405                        break;
1406                    }
1407                }
1408            }
1409            }
1410            else
1411            {
1412                isMatched = 0;
1413            }
1414        }
1415        else
1416        {
1417            isMatched = 0;
1418        }
1419
1420        /* Check channel */
1421        /* Add check channel to solve the bug #31222 */
1422        if (isMatched) {
1423            if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS)) != 0xffff) {
1424                if ((length = zmw_rx_buf_readb(dev, buf, offset+1)) == 1) {
1425                    channel = zmw_rx_buf_readb(dev, buf, offset+2);
1426                    if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) {
1427                        frequency = 0;
1428                    } else {
1429                        frequency = zfChNumToFreq(dev, channel, 0);;
1430                    }
1431                } else {
1432                    frequency = 0;
1433                }
1434            } else {
1435                frequency = wd->sta.currentFrequency;
1436            }
1437
1438            if (frequency != 0) {
1439                if ( ((frequency > 3000) && (pBssInfo->frequency > 3000))
1440                     || ((frequency < 3000) && (pBssInfo->frequency < 3000)) ) {
1441                    /* redundant */
1442                    break;
1443                }
1444            }
1445        }
1446
1447        pBssInfo = pBssInfo->next;
1448    }
1449
1450    if ( i == wd->sta.bssList.bssCount )
1451    {
1452        pBssInfo = NULL;
1453    }
1454
1455    return pBssInfo;
1456}
1457
1458u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf,
1459        struct zsWlanProbeRspFrameHeader *pProbeRspHeader,
1460        struct zsBssInfo* pBssInfo, struct zsAdditionInfo* AddInfo, u8_t type)
1461{
1462    u8_t    length, channel, is5G;
1463    u16_t   i, offset;
1464    u8_t    apQosInfo;
1465    u16_t    eachIElength = 0;
1466    u16_t   accumulateLen = 0;
1467
1468    zmw_get_wlan_dev(dev);
1469
1470    if ((type == 1) && ((pBssInfo->flag & ZM_BSS_INFO_VALID_BIT) != 0))
1471    {
1472        goto zlUpdateRssi;
1473    }
1474
1475    /* get SSID */
1476    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff )
1477    {
1478        zm_debug_msg0("EID(SSID) not found");
1479        goto zlError;
1480    }
1481
1482    length = zmw_rx_buf_readb(dev, buf, offset+1);
1483
1484        {
1485                u8_t Show_Flag = 0;
1486                zfwGetShowZeroLengthSSID(dev, &Show_Flag);
1487
1488                if(Show_Flag)
1489                {
1490                        if (length > ZM_MAX_SSID_LENGTH )
1491                        {
1492                                zm_debug_msg0("EID(SSID) is invalid");
1493                                goto zlError;
1494                        }
1495                }
1496                else
1497                {
1498    if ( length == 0 || length > ZM_MAX_SSID_LENGTH )
1499    {
1500        zm_debug_msg0("EID(SSID) is invalid");
1501        goto zlError;
1502    }
1503
1504                }
1505        }
1506    zfCopyFromRxBuffer(dev, buf, pBssInfo->ssid, offset, length+2);
1507
1508    /* get DS parameter */
1509    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS)) != 0xffff )
1510    {
1511        length = zmw_rx_buf_readb(dev, buf, offset+1);
1512        if ( length != 1 )
1513        {
1514            zm_msg0_mm(ZM_LV_0, "Abnormal DS Param Set IE");
1515            goto zlError;
1516        }
1517        channel = zmw_rx_buf_readb(dev, buf, offset+2);
1518
1519        if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0)
1520        {
1521            goto zlError2;
1522        }
1523
1524        pBssInfo->frequency = zfChNumToFreq(dev, channel, 0); // auto check
1525        pBssInfo->channel = channel;
1526
1527
1528    }
1529    else
1530    {
1531        /* DS parameter not found */
1532        pBssInfo->frequency = wd->sta.currentFrequency;
1533        pBssInfo->channel = zfChFreqToNum(wd->sta.currentFrequency, &is5G);
1534    }
1535
1536    /* initialize security type */
1537    pBssInfo->securityType = ZM_SECURITY_TYPE_NONE;
1538
1539    /* get macaddr */
1540    for( i=0; i<6; i++ )
1541    {
1542        pBssInfo->macaddr[i] = pProbeRspHeader->sa[i];
1543    }
1544
1545    /* get bssid */
1546    for( i=0; i<6; i++ )
1547    {
1548        pBssInfo->bssid[i] = pProbeRspHeader->bssid[i];
1549    }
1550
1551    /* get timestamp */
1552    for( i=0; i<8; i++ )
1553    {
1554        pBssInfo->timeStamp[i] = pProbeRspHeader->timeStamp[i];
1555    }
1556
1557    /* get beacon interval */
1558    pBssInfo->beaconInterval[0] = pProbeRspHeader->beaconInterval[0];
1559    pBssInfo->beaconInterval[1] = pProbeRspHeader->beaconInterval[1];
1560
1561    /* get capability */
1562    pBssInfo->capability[0] = pProbeRspHeader->capability[0];
1563    pBssInfo->capability[1] = pProbeRspHeader->capability[1];
1564
1565    /* Copy frame body */
1566    offset = 36;            // Copy from the start of variable IE
1567    pBssInfo->frameBodysize = zfwBufGetSize(dev, buf)-offset;
1568    if (pBssInfo->frameBodysize > (ZM_MAX_PROBE_FRAME_BODY_SIZE-1))
1569    {
1570        pBssInfo->frameBodysize = ZM_MAX_PROBE_FRAME_BODY_SIZE-1;
1571    }
1572    accumulateLen = 0;
1573    do
1574    {
1575        eachIElength = zmw_rx_buf_readb(dev, buf, offset + accumulateLen+1) + 2;  //Len+(EID+Data)
1576
1577        if ( (eachIElength >= 2)
1578             && ((accumulateLen + eachIElength) <= pBssInfo->frameBodysize) )
1579        {
1580            zfCopyFromRxBuffer(dev, buf, pBssInfo->frameBody+accumulateLen, offset+accumulateLen, eachIElength);
1581            accumulateLen+=(u16_t)eachIElength;
1582        }
1583        else
1584        {
1585            zm_msg0_mm(ZM_LV_1, "probersp frameBodysize abnormal");
1586            break;
1587        }
1588    }
1589    while(accumulateLen < pBssInfo->frameBodysize);
1590    pBssInfo->frameBodysize = accumulateLen;
1591
1592    /* get supported rates */
1593    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff )
1594    {
1595        zm_debug_msg0("EID(supported rates) not found");
1596        goto zlError;
1597    }
1598
1599    length = zmw_rx_buf_readb(dev, buf, offset+1);
1600    if ( length == 0 || length > ZM_MAX_SUPP_RATES_IE_SIZE)
1601    {
1602        zm_msg0_mm(ZM_LV_0, "Supported rates IE length abnormal");
1603        goto zlError;
1604    }
1605    zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2);
1606
1607
1608
1609    /* get Country information */
1610    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY)) != 0xffff )
1611    {
1612        length = zmw_rx_buf_readb(dev, buf, offset+1);
1613        if (length > ZM_MAX_COUNTRY_INFO_SIZE)
1614        {
1615            length = ZM_MAX_COUNTRY_INFO_SIZE;
1616        }
1617        zfCopyFromRxBuffer(dev, buf, pBssInfo->countryInfo, offset, length+2);
1618        /* check 802.11d support data */
1619        if (wd->sta.b802_11D)
1620        {
1621            zfHpGetRegulationTablefromISO(dev, (u8_t *)&pBssInfo->countryInfo, 3);
1622            /* only set regulatory one time */
1623            wd->sta.b802_11D = 0;
1624        }
1625    }
1626
1627    /* get ERP information */
1628    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff )
1629    {
1630        pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2);
1631    }
1632
1633    /* get extended supported rates */
1634    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff )
1635    {
1636        length = zmw_rx_buf_readb(dev, buf, offset+1);
1637        if (length > ZM_MAX_SUPP_RATES_IE_SIZE)
1638        {
1639            zm_msg0_mm(ZM_LV_0, "Extended rates IE length abnormal");
1640            goto zlError;
1641        }
1642        zfCopyFromRxBuffer(dev, buf, pBssInfo->extSupportedRates, offset, length+2);
1643    }
1644    else
1645    {
1646        pBssInfo->extSupportedRates[0] = 0;
1647        pBssInfo->extSupportedRates[1] = 0;
1648    }
1649
1650    /* get WPA IE */
1651    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff )
1652    {
1653        length = zmw_rx_buf_readb(dev, buf, offset+1);
1654        if (length > ZM_MAX_IE_SIZE)
1655        {
1656            length = ZM_MAX_IE_SIZE;
1657        }
1658        zfCopyFromRxBuffer(dev, buf, pBssInfo->wpaIe, offset, length+2);
1659        pBssInfo->securityType = ZM_SECURITY_TYPE_WPA;
1660    }
1661    else
1662    {
1663        pBssInfo->wpaIe[1] = 0;
1664    }
1665
1666    /* get WPS IE */
1667    if ((offset = zfFindWifiElement(dev, buf, 4, 0xff)) != 0xffff)
1668    {
1669        length = zmw_rx_buf_readb(dev, buf, offset+1);
1670        if (length > ZM_MAX_WPS_IE_SIZE )
1671        {
1672            length = ZM_MAX_WPS_IE_SIZE;
1673        }
1674        zfCopyFromRxBuffer(dev, buf, pBssInfo->wscIe, offset, length+2);
1675    }
1676    else
1677    {
1678        pBssInfo->wscIe[1] = 0;
1679    }
1680
1681    /* get SuperG IE */
1682    if ((offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE)) != 0xffff)
1683    {
1684        pBssInfo->apCap |= ZM_SuperG_AP;
1685    }
1686
1687    /* get XR IE */
1688    if ((offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE)) != 0xffff)
1689    {
1690        pBssInfo->apCap |= ZM_XR_AP;
1691    }
1692
1693    /* get RSN IE */
1694    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff )
1695    {
1696        length = zmw_rx_buf_readb(dev, buf, offset+1);
1697        if (length > ZM_MAX_IE_SIZE)
1698        {
1699            length = ZM_MAX_IE_SIZE;
1700        }
1701        zfCopyFromRxBuffer(dev, buf, pBssInfo->rsnIe, offset, length+2);
1702        pBssInfo->securityType = ZM_SECURITY_TYPE_WPA;
1703    }
1704    else
1705    {
1706        pBssInfo->rsnIe[1] = 0;
1707    }
1708#ifdef ZM_ENABLE_CENC
1709    /* get CENC IE */
1710    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff )
1711    {
1712        length = zmw_rx_buf_readb(dev, buf, offset+1);
1713        if (length > ZM_MAX_IE_SIZE )
1714        {
1715            length = ZM_MAX_IE_SIZE;
1716        }
1717        zfCopyFromRxBuffer(dev, buf, pBssInfo->cencIe, offset, length+2);
1718        pBssInfo->securityType = ZM_SECURITY_TYPE_CENC;
1719        pBssInfo->capability[0] &= 0xffef;
1720    }
1721    else
1722    {
1723        pBssInfo->cencIe[1] = 0;
1724    }
1725#endif //ZM_ENABLE_CENC
1726    /* get WME Parameter IE, probe rsp may contain WME parameter element */
1727    //if ( wd->bQoSEnable )
1728    {
1729        if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff)
1730        {
1731            apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80;
1732            pBssInfo->wmeSupport = 1 | apQosInfo;
1733        }
1734        else if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff)
1735        {
1736            apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80;
1737            pBssInfo->wmeSupport = 1  | apQosInfo;
1738        }
1739        else
1740        {
1741            pBssInfo->wmeSupport = 0;
1742        }
1743    }
1744    //CWYang(+)
1745    if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff)
1746    {
1747        /* 11n AP */
1748        pBssInfo->EnableHT = 1;
1749        if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x02)
1750        {
1751            pBssInfo->enableHT40 = 1;
1752        }
1753        else
1754        {
1755            pBssInfo->enableHT40 = 0;
1756        }
1757
1758        if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x40)
1759        {
1760            pBssInfo->SG40 = 1;
1761        }
1762        else
1763        {
1764            pBssInfo->SG40 = 0;
1765        }
1766    }
1767    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
1768    {
1769        /* 11n AP */
1770        pBssInfo->EnableHT = 1;
1771        pBssInfo->apCap |= ZM_All11N_AP;
1772        if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x02)
1773        {
1774            pBssInfo->enableHT40 = 1;
1775        }
1776        else
1777        {
1778            pBssInfo->enableHT40 = 0;
1779        }
1780
1781        if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x40)
1782        {
1783            pBssInfo->SG40 = 1;
1784        }
1785        else
1786        {
1787            pBssInfo->SG40 = 0;
1788        }
1789    }
1790    else
1791    {
1792        pBssInfo->EnableHT = 0;
1793    }
1794    /* HT information */
1795    if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)
1796    {
1797        /* atheros pre n */
1798        pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+2) & 0x03;
1799    }
1800    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff)
1801    {
1802        /* pre n 2.0 standard */
1803        pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+3) & 0x03;
1804    }
1805    else
1806    {
1807        pBssInfo->extChOffset = 0;
1808    }
1809
1810    if ( (pBssInfo->enableHT40 == 1)
1811         && ((pBssInfo->extChOffset != 1) && (pBssInfo->extChOffset != 3)) )
1812    {
1813        pBssInfo->enableHT40 = 0;
1814    }
1815
1816    if (pBssInfo->enableHT40 == 1)
1817    {
1818        if (zfHpIsAllowedChannel(dev, pBssInfo->frequency+((pBssInfo->extChOffset==1)?20:-20)) == 0)
1819        {
1820            /* if extension channel is not an allowed channel, treat AP as non-HT mode */
1821            pBssInfo->EnableHT = 0;
1822            pBssInfo->enableHT40 = 0;
1823            pBssInfo->extChOffset = 0;
1824        }
1825    }
1826
1827    /* get ATH Extended Capability */
1828    if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)&&
1829        ((offset = zfFindBrdcmMrvlRlnkExtCap(dev, buf)) == 0xffff))
1830
1831    {
1832        pBssInfo->athOwlAp = 1;
1833    }
1834    else
1835    {
1836        pBssInfo->athOwlAp = 0;
1837    }
1838
1839    /* get Broadcom Extended Capability */
1840    if ( (pBssInfo->EnableHT == 1) //((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)
1841         && ((offset = zfFindBroadcomExtCap(dev, buf)) != 0xffff) )
1842    {
1843        pBssInfo->broadcomHTAp = 1;
1844    }
1845    else
1846    {
1847        pBssInfo->broadcomHTAp = 0;
1848    }
1849
1850    /* get Marvel Extended Capability */
1851    if ((offset = zfFindMarvelExtCap(dev, buf)) != 0xffff)
1852    {
1853        pBssInfo->marvelAp = 1;
1854    }
1855    else
1856    {
1857        pBssInfo->marvelAp = 0;
1858    }
1859
1860    /* get ATIM window */
1861    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS)) != 0xffff )
1862    {
1863        pBssInfo->atimWindow = zmw_rx_buf_readh(dev, buf,offset+2);
1864    }
1865
1866    /* Fit for support mode */
1867    if (pBssInfo->frequency > 3000) {
1868        if (wd->supportMode & ZM_WIRELESS_MODE_5_N) {
1869#if 0
1870            if (wd->supportMode & ZM_WIRELESS_MODE_5_54) {
1871                /* support mode: a, n */
1872                /* do nothing */
1873            } else {
1874                /* support mode: n */
1875                /* reject non-n bss info */
1876                if (!pBssInfo->EnableHT) {
1877                    goto zlError2;
1878                }
1879            }
1880#endif
1881        } else {
1882            if (wd->supportMode & ZM_WIRELESS_MODE_5_54) {
1883                /* support mode: a */
1884                /* delete n mode information */
1885                pBssInfo->EnableHT = 0;
1886                pBssInfo->enableHT40 = 0;
1887                pBssInfo->apCap &= (~ZM_All11N_AP);
1888                pBssInfo->extChOffset = 0;
1889                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1890                            pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY);
1891                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1892                            pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY);
1893                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1894                            pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1895                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1896                            pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION);
1897            } else {
1898                /* support mode: none */
1899                goto zlError2;
1900            }
1901        }
1902    } else {
1903        if (wd->supportMode & ZM_WIRELESS_MODE_24_N) {
1904#if 0
1905            if (wd->supportMode & ZM_WIRELESS_MODE_24_54) {
1906                if (wd->supportMode & ZM_WIRELESS_MODE_24_11) {
1907                    /* support mode: b, g, n */
1908                    /* do nothing */
1909                } else {
1910                    /* support mode: g, n */
1911                    /* reject b-only bss info */
1912                    if ( (!pBssInfo->EnableHT)
1913                         && (pBssInfo->extSupportedRates[1] == 0) ) {
1914                         goto zlError2;
1915                    }
1916                }
1917            } else {
1918                if (wd->supportMode & ZM_WIRELESS_MODE_24_11) {
1919                    /* support mode: b, n */
1920                    /* 1. reject g-only bss info
1921                     * 2. if non g-only, delete g mode information
1922                     */
1923                    if ( !pBssInfo->EnableHT ) {
1924                        if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates)
1925                             || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) {
1926                            goto zlError2;
1927                        } else {
1928                            zfGatherBMode(dev, pBssInfo->supportedRates,
1929                                          pBssInfo->extSupportedRates);
1930                            pBssInfo->erp = 0;
1931
1932                            pBssInfo->frameBodysize = zfRemoveElement(dev,
1933                                pBssInfo->frameBody, pBssInfo->frameBodysize,
1934                                ZM_WLAN_EID_ERP);
1935                            pBssInfo->frameBodysize = zfRemoveElement(dev,
1936                                pBssInfo->frameBody, pBssInfo->frameBodysize,
1937                                ZM_WLAN_EID_EXTENDED_RATE);
1938
1939                            pBssInfo->frameBodysize = zfUpdateElement(dev,
1940                                pBssInfo->frameBody, pBssInfo->frameBodysize,
1941                                pBssInfo->supportedRates);
1942                        }
1943                    }
1944                } else {
1945                    /* support mode: n */
1946                    /* reject non-n bss info */
1947                    if (!pBssInfo->EnableHT) {
1948                        goto zlError2;
1949                    }
1950                }
1951            }
1952#endif
1953        } else {
1954            /* delete n mode information */
1955            pBssInfo->EnableHT = 0;
1956            pBssInfo->enableHT40 = 0;
1957            pBssInfo->apCap &= (~ZM_All11N_AP);
1958            pBssInfo->extChOffset = 0;
1959            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1960                        pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY);
1961            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1962                        pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY);
1963            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1964                        pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1965            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1966                        pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION);
1967
1968            if (wd->supportMode & ZM_WIRELESS_MODE_24_54) {
1969#if 0
1970                if (wd->supportMode & ZM_WIRELESS_MODE_24_11) {
1971                    /* support mode: b, g */
1972                    /* delete n mode information */
1973                } else {
1974                    /* support mode: g */
1975                    /* delete n mode information */
1976                    /* reject b-only bss info */
1977                    if (pBssInfo->extSupportedRates[1] == 0) {
1978                         goto zlError2;
1979                    }
1980                }
1981#endif
1982            } else {
1983                if (wd->supportMode & ZM_WIRELESS_MODE_24_11) {
1984                    /* support mode: b */
1985                    /* delete n mode information */
1986                    if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates)
1987                         || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) {
1988                        goto zlError2;
1989                    } else {
1990                        zfGatherBMode(dev, pBssInfo->supportedRates,
1991                                          pBssInfo->extSupportedRates);
1992                        pBssInfo->erp = 0;
1993
1994                        pBssInfo->frameBodysize = zfRemoveElement(dev,
1995                            pBssInfo->frameBody, pBssInfo->frameBodysize,
1996                            ZM_WLAN_EID_ERP);
1997                        pBssInfo->frameBodysize = zfRemoveElement(dev,
1998                            pBssInfo->frameBody, pBssInfo->frameBodysize,
1999                            ZM_WLAN_EID_EXTENDED_RATE);
2000
2001                        pBssInfo->frameBodysize = zfUpdateElement(dev,
2002                            pBssInfo->frameBody, pBssInfo->frameBodysize,
2003                            pBssInfo->supportedRates);
2004                    }
2005                } else {
2006                    /* support mode: none */
2007                    goto zlError2;
2008                }
2009            }
2010        }
2011    }
2012
2013    pBssInfo->flag |= ZM_BSS_INFO_VALID_BIT;
2014
2015zlUpdateRssi:
2016    /* Update Timer information */
2017    pBssInfo->tick = wd->tick;
2018
2019    /* Update ERP information */
2020    if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff )
2021    {
2022        pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2);
2023    }
2024
2025    if( (s8_t)pBssInfo->signalStrength < (s8_t)AddInfo->Tail.Data.SignalStrength1 )
2026    {
2027        /* Update signal strength */
2028        pBssInfo->signalStrength = (u8_t)AddInfo->Tail.Data.SignalStrength1;
2029        /* Update signal quality */
2030        pBssInfo->signalQuality = (u8_t)(AddInfo->Tail.Data.SignalStrength1 * 2);
2031
2032        /* Update the sorting value  */
2033        pBssInfo->sortValue = zfComputeBssInfoWeightValue(dev,
2034                                               (pBssInfo->supportedRates[6] + pBssInfo->extSupportedRates[0]),
2035                                               pBssInfo->EnableHT,
2036                                               pBssInfo->enableHT40,
2037                                               pBssInfo->signalStrength);
2038    }
2039
2040    return 0;
2041
2042zlError:
2043
2044    return 1;
2045
2046zlError2:
2047
2048    return 2;
2049}
2050
2051void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) //CWYang(m)
2052{
2053    /* Parse TIM and send PS-POLL in power saving mode */
2054    struct zsWlanBeaconFrameHeader*  pBeaconHeader;
2055    struct zsBssInfo* pBssInfo;
2056    u8_t   pBuf[sizeof(struct zsWlanBeaconFrameHeader)];
2057    u8_t   bssid[6];
2058    int    res;
2059
2060    zmw_get_wlan_dev(dev);
2061
2062    zmw_declare_for_critical_section();
2063
2064    /* sta routine jobs */
2065    zfStaProtErpMonitor(dev, buf);  /* check protection mode */
2066
2067    if (zfStaIsConnected(dev))
2068    {
2069        ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid);
2070
2071        if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2072        {
2073            if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6) )
2074            {
2075                zfPowerSavingMgrProcessBeacon(dev, buf);
2076                zfStaUpdateWmeParameter(dev, buf);
2077                if (wd->sta.DFSEnable)
2078                    zfStaUpdateDot11HDFS(dev, buf);
2079                if (wd->sta.TPCEnable)
2080                    zfStaUpdateDot11HTPC(dev, buf);
2081                /* update signal strength and signal quality */
2082                zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1,
2083                        AddInfo->Tail.Data.SignalQuality); //CWYang(+)
2084                wd->sta.rxBeaconCount++;
2085            }
2086        }
2087        else if ( wd->wlanMode == ZM_MODE_IBSS )
2088        {
2089            if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A3_OFFSET, 6) )
2090            {
2091                int res;
2092                struct zsPartnerNotifyEvent event;
2093
2094                zm_debug_msg0("20070916 Receive opposite Beacon!");
2095                zmw_enter_critical_section(dev);
2096                wd->sta.ibssReceiveBeaconCount++;
2097                zmw_leave_critical_section(dev);
2098
2099                res = zfStaSetOppositeInfoFromRxBuf(dev, buf);
2100                if ( res == 0 )
2101                {
2102                    // New peer station found. Notify the wrapper now
2103                    zfInitPartnerNotifyEvent(dev, buf, &event);
2104                    if (wd->zfcbIbssPartnerNotify != NULL)
2105                    {
2106                        wd->zfcbIbssPartnerNotify(dev, 1, &event);
2107                    }
2108                }
2109                /* update signal strength and signal quality */
2110                zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1,
2111                        AddInfo->Tail.Data.SignalQuality); //CWYang(+)
2112            }
2113            //else if ( wd->sta.ibssPartnerStatus == ZM_IBSS_PARTNER_LOST )
2114            // Why does this happen in IBSS?? The impact of Vista since
2115            // we need to tell it the BSSID
2116#if 0
2117            else if ( wd->sta.oppositeCount == 0 )
2118            {   /* IBSS merge if SSID matched */
2119                if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff )
2120                {
2121                    if ( (wd->sta.ssidLen == zmw_buf_readb(dev, buf, offset+1))&&
2122                         (zfRxBufferEqualToStr(dev, buf, wd->sta.ssid,
2123                                               offset+2, wd->sta.ssidLen)) )
2124                    {
2125                        capabilityInfo = zmw_buf_readh(dev, buf, 34);
2126
2127                        if ( capabilityInfo & ZM_BIT_1 )
2128                        {
2129                            if ( (wd->sta.capability[0] & ZM_BIT_4) ==
2130                                 (capabilityInfo & ZM_BIT_4) )
2131                            {
2132                                zm_debug_msg0("IBSS merge");
2133                                zfCopyFromRxBuffer(dev, buf, bssid,
2134                                                   ZM_WLAN_HEADER_A3_OFFSET, 6);
2135                                zfUpdateBssid(dev, bssid);
2136                            }
2137                        }
2138                    }
2139                }
2140            }
2141#endif
2142        }
2143    }
2144
2145    /* return if not channel scan */
2146    if ( !wd->sta.bChannelScan )
2147    {
2148        goto zlReturn;
2149    }
2150
2151    zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanBeaconFrameHeader));
2152    pBeaconHeader = (struct zsWlanBeaconFrameHeader*) pBuf;
2153
2154    zmw_enter_critical_section(dev);
2155
2156    //zm_debug_msg1("bss count = ", wd->sta.bssList.bssCount);
2157
2158    pBssInfo = zfStaFindBssInfo(dev, buf, pBeaconHeader);
2159
2160    if ( pBssInfo == NULL )
2161    {
2162        /* Allocate a new entry if BSS not in the scan list */
2163        pBssInfo = zfBssInfoAllocate(dev);
2164        if (pBssInfo != NULL)
2165        {
2166            res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 0);
2167            //zfDumpSSID(pBssInfo->ssid[1], &(pBssInfo->ssid[2]));
2168            if ( res != 0 )
2169            {
2170                zfBssInfoFree(dev, pBssInfo);
2171            }
2172            else
2173            {
2174                zfBssInfoInsertToList(dev, pBssInfo);
2175            }
2176        }
2177    }
2178    else
2179    {
2180        res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 1);
2181        if (res == 2)
2182        {
2183            zfBssInfoRemoveFromList(dev, pBssInfo);
2184            zfBssInfoFree(dev, pBssInfo);
2185        }
2186        else if ( wd->wlanMode == ZM_MODE_IBSS )
2187        {
2188            int idx;
2189
2190            // It would reset the alive counter if the peer station is found!
2191            zfStaFindFreeOpposite(dev, (u16_t *)pBssInfo->macaddr, &idx);
2192        }
2193    }
2194
2195    zmw_leave_critical_section(dev);
2196
2197zlReturn:
2198
2199    return;
2200}
2201
2202
2203void zfAuthFreqCompleteCb(zdev_t* dev)
2204{
2205    zmw_get_wlan_dev(dev);
2206    zmw_declare_for_critical_section();
2207
2208    zmw_enter_critical_section(dev);
2209
2210    if (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_COMPLETED)
2211    {
2212        zm_debug_msg0("ZM_STA_CONN_STATE_ASSOCIATE");
2213        wd->sta.connectTimer = wd->tick;
2214        wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE;
2215    }
2216
2217    zmw_leave_critical_section(dev);
2218    return;
2219}
2220
2221/************************************************************************/
2222/*                                                                      */
2223/*    FUNCTION DESCRIPTION                  zfProcessAuth               */
2224/*      Process authenticate management frame.                          */
2225/*                                                                      */
2226/*    INPUTS                                                            */
2227/*      dev : device pointer                                            */
2228/*      buf : auth frame buffer                                         */
2229/*                                                                      */
2230/*    OUTPUTS                                                           */
2231/*      none                                                            */
2232/*                                                                      */
2233/*    AUTHOR                                                            */
2234/*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
2235/*                                                                      */
2236/************************************************************************/
2237/* Note : AP allows one authenticating STA at a time, does not          */
2238/*        support multiple authentication process. Make sure            */
2239/*        authentication state machine will not be blocked due          */
2240/*        to incompleted authentication handshake.                      */
2241void zfStaProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
2242{
2243    struct zsWlanAuthFrameHeader* pAuthFrame;
2244    u8_t  pBuf[sizeof(struct zsWlanAuthFrameHeader)];
2245    u32_t p1, p2;
2246
2247    zmw_get_wlan_dev(dev);
2248    zmw_declare_for_critical_section();
2249
2250    if ( !zfStaIsConnecting(dev) )
2251    {
2252        return;
2253    }
2254
2255    pAuthFrame = (struct zsWlanAuthFrameHeader*) pBuf;
2256    zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAuthFrameHeader));
2257
2258    if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN )
2259    {
2260        if ( (zmw_le16_to_cpu(pAuthFrame->seq) == 2)&&
2261             (zmw_le16_to_cpu(pAuthFrame->algo) == 0)&&
2262             (zmw_le16_to_cpu(pAuthFrame->status) == 0) )
2263        {
2264
2265            zmw_enter_critical_section(dev);
2266            wd->sta.connectTimer = wd->tick;
2267            zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_COMPLETED");
2268            wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_COMPLETED;
2269            zmw_leave_critical_section(dev);
2270
2271            //Set channel according to AP's configuration
2272            //Move to here because of Cisco 11n AP feature
2273            zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2274                    wd->ExtOffset, zfAuthFreqCompleteCb);
2275
2276            /* send association frame */
2277            if ( wd->sta.connectByReasso )
2278            {
2279                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCREQ,
2280                              wd->sta.bssid, 0, 0, 0);
2281            }
2282            else
2283            {
2284                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ,
2285                              wd->sta.bssid, 0, 0, 0);
2286            }
2287
2288
2289        }
2290        else
2291        {
2292            zm_debug_msg1("authentication failed, status = ",
2293                          pAuthFrame->status);
2294
2295            if (wd->sta.authMode == ZM_AUTH_MODE_AUTO)
2296            {
2297                wd->sta.bIsSharedKey = 1;
2298                zfStaStartConnect(dev, wd->sta.bIsSharedKey);
2299            }
2300            else
2301            {
2302                zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2303                zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2304            }
2305        }
2306    }
2307    else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1 )
2308    {
2309        if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1) &&
2310             (zmw_le16_to_cpu(pAuthFrame->seq) == 2) &&
2311             (zmw_le16_to_cpu(pAuthFrame->status) == 0))
2312              //&& (pAuthFrame->challengeText[1] <= 255) )
2313        {
2314            zfMemoryCopy(wd->sta.challengeText, pAuthFrame->challengeText,
2315                         pAuthFrame->challengeText[1]+2);
2316
2317            /* send the 3rd authentication frame */
2318            p1 = 0x30001;
2319            p2 = 0;
2320            zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH,
2321                          wd->sta.bssid, p1, p2, 0);
2322
2323            zmw_enter_critical_section(dev);
2324            wd->sta.connectTimer = wd->tick;
2325
2326            zm_debug_msg0("ZM_STA_SUB_STATE_AUTH_SHARE_2");
2327            wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_2;
2328            zmw_leave_critical_section(dev);
2329        }
2330        else
2331        {
2332            zm_debug_msg1("authentication failed, status = ",
2333                          pAuthFrame->status);
2334
2335            zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2336            zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2337        }
2338    }
2339    else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2 )
2340    {
2341        if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1)&&
2342             (zmw_le16_to_cpu(pAuthFrame->seq) == 4)&&
2343             (zmw_le16_to_cpu(pAuthFrame->status) == 0) )
2344        {
2345            //Set channel according to AP's configuration
2346            //Move to here because of Cisco 11n AP feature
2347            zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2348                    wd->ExtOffset, NULL);
2349
2350            /* send association frame */
2351            zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ,
2352                          wd->sta.bssid, 0, 0, 0);
2353
2354            zmw_enter_critical_section(dev);
2355            wd->sta.connectTimer = wd->tick;
2356
2357            zm_debug_msg0("ZM_STA_SUB_STATE_ASSOCIATE");
2358            wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE;
2359            zmw_leave_critical_section(dev);
2360        }
2361        else
2362        {
2363            zm_debug_msg1("authentication failed, status = ",
2364                          pAuthFrame->status);
2365
2366            zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2367            zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2368        }
2369    }
2370    else
2371    {
2372        zm_debug_msg0("unknown case");
2373    }
2374}
2375
2376void zfStaProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
2377{
2378
2379    return;
2380}
2381
2382void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf)
2383{
2384    struct zsWlanAssoFrameHeader* pAssoFrame;
2385    u8_t  pBuf[sizeof(struct zsWlanAssoFrameHeader)];
2386    u16_t offset;
2387    u32_t i;
2388    u32_t oneTxStreamCap;
2389
2390    zmw_get_wlan_dev(dev);
2391
2392    if ( !zfStaIsConnecting(dev) )
2393    {
2394        return;
2395    }
2396
2397    pAssoFrame = (struct zsWlanAssoFrameHeader*) pBuf;
2398    zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAssoFrameHeader));
2399
2400    if ( wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE )
2401    {
2402        if ( pAssoFrame->status == 0 )
2403        {
2404            zm_debug_msg0("ZM_STA_STATE_CONNECTED");
2405
2406            if (wd->sta.EnableHT == 1)
2407            {
2408                wd->sta.wmeConnected = 1;
2409            }
2410            if ((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled
2411            {
2412                /* Asoc rsp may contain WME parameter element */
2413                if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff)
2414                {
2415                    zm_debug_msg0("WME enable");
2416                    wd->sta.wmeConnected = 1;
2417                    if ((wd->sta.wmeEnabled & ZM_STA_UAPSD_ENABLE_BIT) != 0)
2418                    {
2419                        if ((zmw_rx_buf_readb(dev, buf, offset+8) & 0x80) != 0)
2420                        {
2421                            zm_debug_msg0("UAPSD enable");
2422                            wd->sta.qosInfo = wd->sta.wmeQosInfo;
2423                        }
2424                    }
2425
2426                    zfStaUpdateWmeParameter(dev, buf);
2427                }
2428            }
2429
2430
2431            //Store asoc response frame body, for VISTA only
2432            wd->sta.asocRspFrameBodySize = zfwBufGetSize(dev, buf)-24;
2433            if (wd->sta.asocRspFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
2434            {
2435                wd->sta.asocRspFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
2436            }
2437            for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
2438            {
2439                wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
2440            }
2441
2442            zfStaStoreAsocRspIe(dev, buf);
2443            if (wd->sta.EnableHT &&
2444                ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) != 0) &&
2445                (wd->ExtOffset != 0))
2446            {
2447                wd->sta.htCtrlBandwidth = 1;
2448            }
2449            else
2450            {
2451                wd->sta.htCtrlBandwidth = 0;
2452            }
2453
2454            //Set channel according to AP's configuration
2455            //zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2456            //        wd->ExtOffset, NULL);
2457
2458            if (wd->sta.EnableHT == 1)
2459            {
2460                wd->addbaComplete = 0;
2461
2462                if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 &&
2463                    (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0)
2464                {
2465                    wd->addbaCount = 1;
2466                    zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0);
2467                    zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100);
2468                }
2469            }
2470
2471            /* set RIFS support */
2472            if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode)
2473            {
2474                wd->sta.HT2040 = 1;
2475//                zfHpSetRifs(dev, wd->sta.EnableHT, 1, (wd->sta.currentFrequency < 3000)? 1:0);
2476            }
2477
2478            wd->sta.aid = pAssoFrame->aid & 0x3fff;
2479            wd->sta.oppositeCount = 0;    /* reset opposite count */
2480            zfStaSetOppositeInfoFromRxBuf(dev, buf);
2481
2482            wd->sta.rxBeaconCount = 16;
2483
2484            zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
2485            wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
2486            if (wd->zfcbConnectNotify != NULL)
2487            {
2488                if (wd->sta.EnableHT != 0) /* 11n */
2489                {
2490                        oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
2491                        if (wd->sta.htCtrlBandwidth == 1) /* HT40*/
2492                        {
2493                                        if(oneTxStreamCap) /* one Tx stream */
2494                                    {
2495                                        if (wd->sta.SG40)
2496                                        {
2497                                            wd->CurrentTxRateKbps = 150000;
2498                                                    wd->CurrentRxRateKbps = 300000;
2499                                        }
2500                                        else
2501                                        {
2502                                            wd->CurrentTxRateKbps = 135000;
2503                                                    wd->CurrentRxRateKbps = 270000;
2504                                        }
2505                                    }
2506                                    else /* Two Tx streams */
2507                                    {
2508                                        if (wd->sta.SG40)
2509                                        {
2510                                            wd->CurrentTxRateKbps = 300000;
2511                                                    wd->CurrentRxRateKbps = 300000;
2512                                        }
2513                                        else
2514                                        {
2515                                            wd->CurrentTxRateKbps = 270000;
2516                                                    wd->CurrentRxRateKbps = 270000;
2517                                        }
2518                                    }
2519                        }
2520                        else /* HT20 */
2521                        {
2522                            if(oneTxStreamCap) /* one Tx stream */
2523                                    {
2524                                        wd->CurrentTxRateKbps = 650000;
2525                                                wd->CurrentRxRateKbps = 130000;
2526                                    }
2527                                    else /* Two Tx streams */
2528                                    {
2529                                        wd->CurrentTxRateKbps = 130000;
2530                                            wd->CurrentRxRateKbps = 130000;
2531                                    }
2532                        }
2533                }
2534                else /* 11abg */
2535                {
2536                    if (wd->sta.connection_11b != 0)
2537                    {
2538                        wd->CurrentTxRateKbps = 11000;
2539                                wd->CurrentRxRateKbps = 11000;
2540                    }
2541                    else
2542                    {
2543                        wd->CurrentTxRateKbps = 54000;
2544                                wd->CurrentRxRateKbps = 54000;
2545                            }
2546                }
2547
2548
2549                wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
2550            }
2551            wd->sta.connectByReasso = TRUE;
2552            wd->sta.failCntOfReasso = 0;
2553
2554            zfPowerSavingMgrConnectNotify(dev);
2555
2556            /* Disable here because fixed rate is only for test, TBD. */
2557            //if (wd->sta.EnableHT)
2558            //{
2559            //    wd->txMCS = 7; //Rate = 65Mbps
2560            //    wd->txMT = 2; // Ht rate
2561            //    wd->enableAggregation = 2; // Enable Aggregation
2562            //}
2563        }
2564        else
2565        {
2566            zm_debug_msg1("association failed, status = ",
2567                          pAssoFrame->status);
2568
2569            zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2570            wd->sta.connectByReasso = FALSE;
2571            zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3);
2572        }
2573    }
2574
2575}
2576
2577void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf)
2578{
2579    u16_t offset;
2580    u32_t i;
2581    u16_t length;
2582    u8_t  *htcap;
2583    u8_t  asocBw40 = 0;
2584    u8_t  asocExtOffset = 0;
2585
2586    zmw_get_wlan_dev(dev);
2587
2588    for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
2589    {
2590        wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
2591    }
2592
2593    /* HT capabilities: 28 octets */
2594    if (    ((wd->sta.currentFrequency > 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_5_N))
2595         || ((wd->sta.currentFrequency < 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_24_N)) )
2596    {
2597        /* not 11n AP */
2598        htcap = (u8_t *)&wd->sta.ie.HtCap;
2599        for (i=0; i<28; i++)
2600        {
2601            htcap[i] = 0;
2602        }
2603        wd->BandWidth40 = 0;
2604        wd->ExtOffset = 0;
2605        return;
2606    }
2607
2608    if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff)
2609    {
2610        /* atheros pre n */
2611        zm_debug_msg0("atheros pre n");
2612        htcap = (u8_t *)&wd->sta.ie.HtCap;
2613        htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
2614        htcap[1] = 26;
2615        for (i=1; i<=26; i++)
2616        {
2617            htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
2618            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Capabilities, htcap=", htcap[i+1]);
2619        }
2620    }
2621    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
2622    {
2623        /* pre n 2.0 standard */
2624        zm_debug_msg0("pre n 2.0 standard");
2625        htcap = (u8_t *)&wd->sta.ie.HtCap;
2626        for (i=0; i<28; i++)
2627        {
2628            htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
2629            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Capabilities, htcap=", htcap[i]);
2630        }
2631    }
2632    else
2633    {
2634        /* not 11n AP */
2635        htcap = (u8_t *)&wd->sta.ie.HtCap;
2636        for (i=0; i<28; i++)
2637        {
2638            htcap[i] = 0;
2639        }
2640        wd->BandWidth40 = 0;
2641        wd->ExtOffset = 0;
2642        return;
2643    }
2644
2645    asocBw40 = (u8_t)((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) >> 1);
2646
2647    /* HT information */
2648    if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)
2649    {
2650        /* atheros pre n */
2651        zm_debug_msg0("atheros pre n HTINFO");
2652        length = 22;
2653        htcap = (u8_t *)&wd->sta.ie.HtInfo;
2654        htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
2655        htcap[1] = 22;
2656        for (i=1; i<=22; i++)
2657        {
2658            htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
2659            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Info, htinfo=", htcap[i+1]);
2660        }
2661    }
2662    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff)
2663    {
2664        /* pre n 2.0 standard */
2665        zm_debug_msg0("pre n 2.0 standard HTINFO");
2666        length = zmw_rx_buf_readb(dev, buf, offset + 1);
2667        htcap = (u8_t *)&wd->sta.ie.HtInfo;
2668        for (i=0; i<24; i++)
2669        {
2670            htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
2671            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Info, htinfo=", htcap[i]);
2672        }
2673    }
2674    else
2675    {
2676        zm_debug_msg0("no HTINFO");
2677        htcap = (u8_t *)&wd->sta.ie.HtInfo;
2678        for (i=0; i<24; i++)
2679        {
2680            htcap[i] = 0;
2681        }
2682    }
2683    asocExtOffset = wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetBelow;
2684
2685    if ((wd->sta.EnableHT == 1) && (asocBw40 == 1) && ((asocExtOffset == 1) || (asocExtOffset == 3)))
2686    {
2687        wd->BandWidth40 = asocBw40;
2688        wd->ExtOffset = asocExtOffset;
2689    }
2690    else
2691    {
2692        wd->BandWidth40 = 0;
2693        wd->ExtOffset = 0;
2694    }
2695
2696    return;
2697}
2698
2699void zfStaProcessDeauth(zdev_t* dev, zbuf_t* buf)
2700{
2701    u16_t apMacAddr[3];
2702
2703    zmw_get_wlan_dev(dev);
2704    zmw_declare_for_critical_section();
2705
2706    /* STA : if SA=connected AP then disconnect with AP */
2707    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2708    {
2709        apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2710        apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2711        apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2712        if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2]))
2713        {
2714            if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame
2715            {
2716                if ( zfStaIsConnected(dev) )
2717                {
2718                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DEAUTH, wd->sta.bssid, 2);
2719                }
2720                else if (zfStaIsConnecting(dev))
2721                {
2722                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2723                }
2724                else
2725                {
2726                }
2727            }
2728        }
2729    }
2730    else if ( wd->wlanMode == ZM_MODE_IBSS )
2731    {
2732        u16_t peerMacAddr[3];
2733        u8_t  peerIdx;
2734        s8_t  res;
2735
2736        if ( zfStaIsConnected(dev) )
2737        {
2738            peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
2739            peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2);
2740            peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4);
2741
2742            zmw_enter_critical_section(dev);
2743            res = zfStaFindOppositeByMACAddr(dev, peerMacAddr, &peerIdx);
2744            if ( res == 0 )
2745            {
2746                wd->sta.oppositeInfo[peerIdx].aliveCounter = 0;
2747            }
2748            zmw_leave_critical_section(dev);
2749        }
2750    }
2751}
2752
2753void zfStaProcessDisasoc(zdev_t* dev, zbuf_t* buf)
2754{
2755    u16_t apMacAddr[3];
2756
2757    zmw_get_wlan_dev(dev);
2758
2759    /* STA : if SA=connected AP then disconnect with AP */
2760    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2761    {
2762        apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2763        apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2764        apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2765
2766        if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2]))
2767        {
2768            if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame
2769            {
2770                if ( zfStaIsConnected(dev) )
2771                {
2772                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DISASOC, wd->sta.bssid, 2);
2773                }
2774                else
2775                {
2776                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3);
2777                }
2778            }
2779        }
2780    }
2781}
2782
2783
2784
2785/************************************************************************/
2786/*                                                                      */
2787/*    FUNCTION DESCRIPTION                  zfProcessProbeReq           */
2788/*      Process probe request management frame.                         */
2789/*                                                                      */
2790/*    INPUTS                                                            */
2791/*      dev : device pointer                                            */
2792/*      buf : auth frame buffer                                         */
2793/*                                                                      */
2794/*    OUTPUTS                                                           */
2795/*      none                                                            */
2796/*                                                                      */
2797/*    AUTHOR                                                            */
2798/*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
2799/*                                                                      */
2800/************************************************************************/
2801void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src)
2802{
2803    u16_t offset;
2804    u8_t len;
2805    u16_t i, j;
2806    u16_t sendFlag;
2807
2808    zmw_get_wlan_dev(dev);
2809
2810    /* check mode : AP/IBSS */
2811    if ((wd->wlanMode != ZM_MODE_AP) || (wd->wlanMode != ZM_MODE_IBSS))
2812    {
2813        zm_msg0_mm(ZM_LV_3, "Ignore probe req");
2814        return;
2815    }
2816
2817    /* check SSID */
2818    if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff)
2819    {
2820        zm_msg0_mm(ZM_LV_3, "probe req SSID not found");
2821        return;
2822    }
2823
2824    len = zmw_rx_buf_readb(dev, buf, offset+1);
2825
2826    for (i=0; i<ZM_MAX_AP_SUPPORT; i++)
2827    {
2828        if ((wd->ap.apBitmap & (i<<i)) != 0)
2829        {
2830            sendFlag = 0;
2831            /* boardcast SSID */
2832            if ((len == 0) && (wd->ap.hideSsid[i] == 0))
2833            {
2834                sendFlag = 1;
2835            }
2836            /* Not broadcast SSID */
2837            else if (wd->ap.ssidLen[i] == len)
2838            {
2839                for (j=0; j<len; j++)
2840                {
2841                    if (zmw_rx_buf_readb(dev, buf, offset+1+j)
2842                            != wd->ap.ssid[i][j])
2843                    {
2844                        break;
2845                    }
2846                }
2847                if (j == len)
2848                {
2849                    sendFlag = 1;
2850                }
2851            }
2852            if (sendFlag == 1)
2853            {
2854                /* Send probe response */
2855                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBERSP, src, i, 0, 0);
2856            }
2857        }
2858    }
2859}
2860
2861void zfStaProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo)
2862{
2863    /* return if not channel scan */
2864    // Probe response is sent with unicast. Is this required?
2865    // IBSS would send probe request and the code below would prevent
2866    // the probe response from handling.
2867    #if 0
2868    zmw_get_wlan_dev(dev);
2869
2870    if ( !wd->sta.bChannelScan )
2871    {
2872        return;
2873    }
2874    #endif
2875
2876    zfProcessProbeRsp(dev, buf, AddInfo);
2877}
2878
2879void zfIBSSSetupBssDesc(zdev_t *dev)
2880{
2881#ifdef ZM_ENABLE_IBSS_WPA2PSK
2882    u8_t i;
2883#endif
2884    struct zsBssInfo *pBssInfo;
2885    u16_t offset = 0;
2886
2887    zmw_get_wlan_dev(dev);
2888
2889    pBssInfo = &wd->sta.ibssBssDesc;
2890    zfZeroMemory((u8_t *)pBssInfo, sizeof(struct zsBssInfo));
2891
2892    pBssInfo->signalStrength = 100;
2893
2894    zfMemoryCopy((u8_t *)pBssInfo->macaddr, (u8_t *)wd->macAddr,6);
2895    zfMemoryCopy((u8_t *)pBssInfo->bssid, (u8_t *)wd->sta.bssid, 6);
2896
2897    pBssInfo->beaconInterval[0] = (u8_t)(wd->beaconInterval) ;
2898    pBssInfo->beaconInterval[1] = (u8_t)((wd->beaconInterval) >> 8) ;
2899
2900    pBssInfo->capability[0] = wd->sta.capability[0];
2901    pBssInfo->capability[1] = wd->sta.capability[1];
2902
2903    pBssInfo->ssid[0] = ZM_WLAN_EID_SSID;
2904    pBssInfo->ssid[1] = wd->sta.ssidLen;
2905    zfMemoryCopy((u8_t *)&pBssInfo->ssid[2], (u8_t *)wd->sta.ssid, wd->sta.ssidLen);
2906    zfMemoryCopy((u8_t *)&pBssInfo->frameBody[offset], (u8_t *)pBssInfo->ssid,
2907                 wd->sta.ssidLen + 2);
2908    offset += wd->sta.ssidLen + 2;
2909
2910    /* support rate */
2911
2912    /* DS parameter set */
2913    pBssInfo->channel = zfChFreqToNum(wd->frequency, NULL);
2914    pBssInfo->frequency = wd->frequency;
2915    pBssInfo->atimWindow = wd->sta.atimWindow;
2916
2917#ifdef ZM_ENABLE_IBSS_WPA2PSK
2918    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
2919    {
2920        u8_t rsn[64]=
2921        {
2922                    /* Element ID */
2923                    0x30,
2924                    /* Length */
2925                    0x14,
2926                    /* Version */
2927                    0x01, 0x00,
2928                    /* Group Cipher Suite, default=TKIP */
2929                    0x00, 0x0f, 0xac, 0x04,
2930                    /* Pairwise Cipher Suite Count */
2931                    0x01, 0x00,
2932                    /* Pairwise Cipher Suite, default=TKIP */
2933                    0x00, 0x0f, 0xac, 0x02,
2934                    /* Authentication and Key Management Suite Count */
2935                    0x01, 0x00,
2936                    /* Authentication type, default=PSK */
2937                    0x00, 0x0f, 0xac, 0x02,
2938                    /* RSN capability */
2939                    0x00, 0x00
2940        };
2941
2942        /* Overwrite Group Cipher Suite by AP's setting */
2943        zfMemoryCopy(rsn+4, zgWpa2AesOui, 4);
2944
2945        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
2946        {
2947            /* Overwrite Pairwise Cipher Suite by AES */
2948            zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
2949        }
2950
2951        // RSN element id
2952        pBssInfo->frameBody[offset++] = ZM_WLAN_EID_RSN_IE ;
2953
2954        // RSN length
2955        pBssInfo->frameBody[offset++] = rsn[1] ;
2956
2957        // RSN information
2958        for(i=0; i<rsn[1]; i++)
2959        {
2960            pBssInfo->frameBody[offset++] = rsn[i+2] ;
2961        }
2962
2963        zfMemoryCopy(pBssInfo->rsnIe, rsn, rsn[1]+2);
2964    }
2965#endif
2966}
2967
2968void zfIbssConnectNetwork(zdev_t* dev)
2969{
2970    struct zsBssInfo* pBssInfo;
2971    struct zsBssInfo tmpBssInfo;
2972    u8_t   macAddr[6], bssid[6], bssNotFound = TRUE;
2973    u16_t  i, j=100;
2974    u16_t  k;
2975    struct zsPartnerNotifyEvent event;
2976    u32_t  channelFlags;
2977    u16_t  oppositeWepStatus;
2978
2979    zmw_get_wlan_dev(dev);
2980
2981    zmw_declare_for_critical_section();
2982
2983    /* change state to CONNECTING and stop the channel scanning */
2984    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
2985    zfPowerSavingMgrWakeup(dev);
2986
2987    /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */
2988    zfUpdateDefaultQosParameter(dev, 0);
2989
2990    wd->sta.bProtectionMode = FALSE;
2991    zfHpSetSlotTime(dev, 1);
2992
2993    /* ESS bit off */
2994    wd->sta.capability[0] &= ~ZM_BIT_0;
2995    /* IBSS bit on */
2996    wd->sta.capability[0] |= ZM_BIT_1;
2997    /* not not use short slot time */
2998    wd->sta.capability[1] &= ~ZM_BIT_2;
2999
3000    wd->sta.wmeConnected = 0;
3001    wd->sta.psMgr.tempWakeUp = 0;
3002    wd->sta.qosInfo = 0;
3003    wd->sta.EnableHT = 0;
3004    wd->BandWidth40 = 0;
3005    wd->ExtOffset = 0;
3006
3007    if ( wd->sta.bssList.bssCount )
3008    {
3009        //Reorder BssList by RSSI--CWYang(+)
3010        zfBssInfoReorderList(dev);
3011
3012        zmw_enter_critical_section(dev);
3013
3014        pBssInfo = wd->sta.bssList.head;
3015
3016        for(i=0; i<wd->sta.bssList.bssCount; i++)
3017        {
3018            // 20070806 #1 Privacy bit
3019            if ( pBssInfo->capability[0] & ZM_BIT_4 )
3020            { // Privacy Ibss network
3021//                zm_debug_msg0("Privacy bit on");
3022                oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
3023
3024                if ( pBssInfo->rsnIe[1] != 0 )
3025                {
3026                    if ( (pBssInfo->rsnIe[7] == 0x01) || (pBssInfo->rsnIe[7] == 0x05) )
3027                    { // WEP-40 & WEP-104
3028//                        zm_debug_msg0("WEP40 or WEP104");
3029                        oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
3030                    }
3031                    else if ( pBssInfo->rsnIe[7] == 0x02 )
3032                    { // TKIP
3033//                        zm_debug_msg0("TKIP");
3034                        oppositeWepStatus = ZM_ENCRYPTION_TKIP;
3035                    }
3036                    else if ( pBssInfo->rsnIe[7] == 0x04 )
3037                    { // AES
3038//                        zm_debug_msg0("CCMP-AES");
3039                        oppositeWepStatus = ZM_ENCRYPTION_AES;
3040                    }
3041                }
3042            }
3043            else
3044            {
3045//                zm_debug_msg0("Privacy bit off");
3046                oppositeWepStatus = ZM_ENCRYPTION_WEP_DISABLED;
3047            }
3048
3049            if ( (zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid,
3050                                  wd->sta.ssidLen))&&
3051                 (wd->sta.ssidLen == pBssInfo->ssid[1])&&
3052                 (oppositeWepStatus == wd->sta.wepStatus) )
3053            {
3054                /* Check support mode */
3055                if (pBssInfo->frequency > 3000) {
3056                    if (   (pBssInfo->EnableHT == 1)
3057                        || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3058                    {
3059                        channelFlags = CHANNEL_A_HT;
3060                        if (pBssInfo->enableHT40 == 1) {
3061                            channelFlags |= CHANNEL_HT40;
3062                        }
3063                    } else {
3064                        channelFlags = CHANNEL_A;
3065                    }
3066                } else {
3067                    if (   (pBssInfo->EnableHT == 1)
3068                        || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3069                    {
3070                        channelFlags = CHANNEL_G_HT;
3071                        if(pBssInfo->enableHT40 == 1) {
3072                            channelFlags |= CHANNEL_HT40;
3073                        }
3074                    } else {
3075                        if (pBssInfo->extSupportedRates[1] == 0) {
3076                            channelFlags = CHANNEL_B;
3077                        } else {
3078                            channelFlags = CHANNEL_G;
3079                        }
3080                    }
3081                }
3082
3083                if (   ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0))
3084                    || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1))
3085                    || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2))
3086                    || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) )
3087                {
3088                    pBssInfo = pBssInfo->next;
3089                    continue;
3090                }
3091
3092                /* Bypass DFS channel */
3093                if (zfHpIsDfsChannelNCS(dev, pBssInfo->frequency))
3094                {
3095                    zm_debug_msg0("Bypass DFS channel");
3096                    continue;
3097                }
3098
3099                /* check IBSS bit */
3100                if ( pBssInfo->capability[0] & ZM_BIT_1 )
3101                {
3102                    /* may check timestamp here */
3103                    j = i;
3104                    break;
3105                }
3106            }
3107
3108            pBssInfo = pBssInfo->next;
3109        }
3110
3111        if ((j < wd->sta.bssList.bssCount) && (pBssInfo != NULL))
3112        {
3113            zfwMemoryCopy((u8_t*)&tmpBssInfo, (u8_t*)(pBssInfo), sizeof(struct zsBssInfo));
3114            pBssInfo = &tmpBssInfo;
3115        }
3116        else
3117        {
3118            pBssInfo = NULL;
3119        }
3120
3121        zmw_leave_critical_section(dev);
3122
3123        //if ( j < wd->sta.bssList.bssCount )
3124        if (pBssInfo != NULL)
3125        {
3126            int res;
3127
3128            zm_debug_msg0("IBSS found");
3129
3130            /* Found IBSS, reset bssNotFoundCount */
3131            zmw_enter_critical_section(dev);
3132            wd->sta.bssNotFoundCount = 0;
3133            zmw_leave_critical_section(dev);
3134
3135            bssNotFound = FALSE;
3136            wd->sta.atimWindow = pBssInfo->atimWindow;
3137            wd->frequency = pBssInfo->frequency;
3138            //wd->sta.flagFreqChanging = 1;
3139            zfCoreSetFrequency(dev, wd->frequency);
3140            zfUpdateBssid(dev, pBssInfo->bssid);
3141            zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO);
3142            zfUpdateSupportRate(dev, pBssInfo->supportedRates);
3143            zfUpdateSupportRate(dev, pBssInfo->extSupportedRates);
3144            wd->beaconInterval = pBssInfo->beaconInterval[0] +
3145                                 (((u16_t) pBssInfo->beaconInterval[1]) << 8);
3146
3147            if (wd->beaconInterval == 0)
3148            {
3149                wd->beaconInterval = 100;
3150            }
3151
3152            /* rsn information element */
3153            if ( pBssInfo->rsnIe[1] != 0 )
3154            {
3155                zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe,
3156                             pBssInfo->rsnIe[1]+2);
3157
3158#ifdef ZM_ENABLE_IBSS_WPA2PSK
3159                /* If not use RSNA , run traditional */
3160                zmw_enter_critical_section(dev);
3161                wd->sta.ibssWpa2Psk = 1;
3162                zmw_leave_critical_section(dev);
3163#endif
3164            }
3165            else
3166            {
3167                wd->sta.rsnIe[1] = 0;
3168            }
3169
3170            /* privacy bit */
3171            if ( pBssInfo->capability[0] & ZM_BIT_4 )
3172            {
3173                wd->sta.capability[0] |= ZM_BIT_4;
3174            }
3175            else
3176            {
3177                wd->sta.capability[0] &= ~ZM_BIT_4;
3178            }
3179
3180            /* preamble type */
3181            wd->preambleTypeInUsed = wd->preambleType;
3182            if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO )
3183            {
3184                if (pBssInfo->capability[0] & ZM_BIT_5)
3185                {
3186                    wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3187                }
3188                else
3189                {
3190                    wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG;
3191                }
3192            }
3193
3194            if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3195            {
3196                wd->sta.capability[0] &= ~ZM_BIT_5;
3197            }
3198            else
3199            {
3200                wd->sta.capability[0] |= ZM_BIT_5;
3201            }
3202
3203            wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12;
3204
3205            if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3206            {
3207                wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3208            }
3209
3210            for (k=0; k<8; k++)
3211            {
3212                wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k];
3213            }
3214            wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0];
3215            wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1];
3216            wd->sta.beaconFrameBody[10] = pBssInfo->capability[0];
3217            wd->sta.beaconFrameBody[11] = pBssInfo->capability[1];
3218            //for (k=12; k<wd->sta.beaconFrameBodySize; k++)
3219            for (k=0; k<pBssInfo->frameBodysize; k++)
3220            {
3221                wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k];
3222            }
3223
3224            zmw_enter_critical_section(dev);
3225            res = zfStaSetOppositeInfoFromBSSInfo(dev, pBssInfo);
3226            if ( res == 0 )
3227            {
3228                zfMemoryCopy(event.bssid, (u8_t *)(pBssInfo->bssid), 6);
3229                zfMemoryCopy(event.peerMacAddr, (u8_t *)(pBssInfo->macaddr), 6);
3230            }
3231            zmw_leave_critical_section(dev);
3232
3233            //zfwIbssPartnerNotify(dev, 1, &event);
3234            goto connect_done;
3235        }
3236    }
3237
3238    /* IBSS not found */
3239    if ( bssNotFound )
3240    {
3241#ifdef ZM_ENABLE_IBSS_WPA2PSK
3242        u16_t offset ;
3243#endif
3244        if ( wd->sta.ibssJoinOnly )
3245        {
3246            zm_debug_msg0("IBSS join only...retry...");
3247            goto retry_ibss;
3248        }
3249
3250        if(wd->sta.bssNotFoundCount<2)
3251        {
3252            zmw_enter_critical_section(dev);
3253            zm_debug_msg1("IBSS not found, do sitesurvey!!  bssNotFoundCount=", wd->sta.bssNotFoundCount);
3254            wd->sta.bssNotFoundCount++;
3255            zmw_leave_critical_section(dev);
3256            goto retry_ibss;
3257        }
3258        else
3259        {
3260            zmw_enter_critical_section(dev);
3261            /* Fail IBSS found, TODO create IBSS */
3262            wd->sta.bssNotFoundCount = 0;
3263            zmw_leave_critical_section(dev);
3264        }
3265
3266
3267        if (zfHpIsDfsChannel(dev, wd->frequency))
3268        {
3269            wd->frequency = zfHpFindFirstNonDfsChannel(dev, wd->frequency > 3000);
3270        }
3271
3272        if( wd->ws.autoSetFrequency == 0 )
3273        { /* Auto set frequency */
3274            zm_debug_msg1("Create Ad Hoc Network Band ", wd->ws.adhocMode);
3275            wd->frequency = zfFindCleanFrequency(dev, wd->ws.adhocMode);
3276            wd->ws.autoSetFrequency = 0xff;
3277        }
3278        zm_debug_msg1("IBSS not found, created one in channel ", wd->frequency);
3279
3280        wd->sta.ibssBssIsCreator = 1;
3281
3282        //wd->sta.flagFreqChanging = 1;
3283        zfCoreSetFrequency(dev, wd->frequency);
3284        if (wd->sta.bDesiredBssid == TRUE)
3285        {
3286            for (k=0; k<6; k++)
3287            {
3288                bssid[k] = wd->sta.desiredBssid[k];
3289            }
3290        }
3291        else
3292        {
3293            #if 1
3294            macAddr[0] = (wd->macAddr[0] & 0xff);
3295            macAddr[1] = (wd->macAddr[0] >> 8);
3296            macAddr[2] = (wd->macAddr[1] & 0xff);
3297            macAddr[3] = (wd->macAddr[1] >> 8);
3298            macAddr[4] = (wd->macAddr[2] & 0xff);
3299            macAddr[5] = (wd->macAddr[2] >> 8);
3300            zfGenerateRandomBSSID(dev, (u8_t *)wd->macAddr, (u8_t *)bssid);
3301            #else
3302            for (k=0; k<6; k++)
3303            {
3304                bssid[k] = (u8_t) zfGetRandomNumber(dev, 0);
3305            }
3306            bssid[0] &= ~ZM_BIT_0;
3307            bssid[0] |= ZM_BIT_1;
3308            #endif
3309        }
3310
3311        zfUpdateBssid(dev, bssid);
3312        //wd->sta.atimWindow = 0x0a;
3313
3314        /* rate information */
3315        if(wd->frequency <= ZM_CH_G_14)  // 2.4 GHz  b+g
3316        {
3317            if ( wd->wfc.bIbssGMode
3318                 && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
3319            {
3320                zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG);
3321            }
3322            else
3323            {
3324                zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_B);
3325            }
3326        } else {
3327            zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG);
3328        }
3329
3330        if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED )
3331        {
3332            wd->sta.capability[0] &= ~ZM_BIT_4;
3333        }
3334        else
3335        {
3336            wd->sta.capability[0] |= ZM_BIT_4;
3337        }
3338
3339        wd->preambleTypeInUsed = wd->preambleType;
3340        if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3341        {
3342            wd->sta.capability[0] &= ~ZM_BIT_5;
3343        }
3344        else
3345        {
3346            wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3347            wd->sta.capability[0] |= ZM_BIT_5;
3348        }
3349
3350        zfIBSSSetupBssDesc(dev);
3351
3352#ifdef ZM_ENABLE_IBSS_WPA2PSK
3353
3354        // 20070411 Add WPA2PSK information to its IBSS network !!!
3355        offset = 0 ;
3356
3357        /* timestamp */
3358        offset += 8 ;
3359
3360        /* beacon interval */
3361        wd->sta.beaconFrameBody[offset++] = (u8_t)(wd->beaconInterval) ;
3362        wd->sta.beaconFrameBody[offset++] = (u8_t)((wd->beaconInterval) >> 8) ;
3363
3364        /* capability information */
3365        wd->sta.beaconFrameBody[offset++] = wd->sta.capability[0] ;
3366        wd->sta.beaconFrameBody[offset++] = wd->sta.capability[1] ;
3367        #if 0
3368        /* ssid */
3369        // ssid element id
3370        wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_SSID ;
3371        // ssid length
3372        wd->sta.beaconFrameBody[offset++] = wd->sta.ssidLen ;
3373        // ssid information
3374        for(i=0; i<wd->sta.ssidLen; i++)
3375        {
3376            wd->sta.beaconFrameBody[offset++] = wd->sta.ssid[i] ;
3377        }
3378
3379        /* support rate */
3380        rateSet = ZM_RATE_SET_CCK ;
3381        if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) )
3382        {
3383            offset += 0 ;
3384        }
3385        else
3386        {
3387            // support rate element id
3388            wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_SUPPORT_RATE ;
3389
3390            // support rate length
3391            lenOffset = offset++;
3392
3393            // support rate information
3394            for (i=0; i<4; i++)
3395            {
3396                if ((wd->bRate & (0x1<<i)) == (0x1<<i))
3397                {
3398                    wd->sta.beaconFrameBody[offset++] =
3399                            zg11bRateTbl[i]+((wd->bRateBasic & (0x1<<i))<<(7-i)) ;
3400                    len++;
3401                }
3402            }
3403
3404            // support rate length
3405            wd->sta.beaconFrameBody[lenOffset] = len ;
3406        }
3407
3408        /* DS parameter set */
3409        // DS parameter set elemet id
3410        wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_DS ;
3411
3412        // DS parameter set length
3413        wd->sta.beaconFrameBody[offset++] = 1 ;
3414
3415        // DS parameter set information
3416        wd->sta.beaconFrameBody[offset++] =
3417                zfChFreqToNum(wd->frequency, NULL) ;
3418
3419        /* IBSS parameter set */
3420        // IBSS parameter set element id
3421        wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_IBSS ;
3422
3423        // IBSS parameter set length
3424        wd->sta.beaconFrameBody[offset++] = 2 ;
3425
3426        // IBSS parameter set information
3427        wd->sta.beaconFrameBody[offset] = wd->sta.atimWindow ;
3428        offset += 2 ;
3429
3430        /* ERP Information and Extended Supported Rates */
3431        if ( wd->wfc.bIbssGMode
3432             && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
3433        {
3434            /* ERP Information */
3435            wd->erpElement = 0;
3436            // ERP element id
3437            wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_ERP ;
3438
3439            // ERP length
3440            wd->sta.beaconFrameBody[offset++] = 1 ;
3441
3442            // ERP information
3443            wd->sta.beaconFrameBody[offset++] = wd->erpElement ;
3444
3445            /* Extended Supported Rates */
3446            if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) )
3447            {
3448                offset += 0 ;
3449            }
3450            else
3451            {
3452                len = 0 ;
3453
3454                // Extended Supported Rates element id
3455                wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_EXTENDED_RATE ;
3456
3457                // Extended Supported Rates length
3458                lenOffset = offset++ ;
3459
3460                // Extended Supported Rates information
3461                for (i=0; i<8; i++)
3462                {
3463                    if ((wd->gRate & (0x1<<i)) == (0x1<<i))
3464                    {
3465                        wd->sta.beaconFrameBody[offset++] =
3466                                     zg11gRateTbl[i]+((wd->gRateBasic & (0x1<<i))<<(7-i));
3467                        len++;
3468                    }
3469                }
3470
3471                // extended support rate length
3472                  wd->sta.beaconFrameBody[lenOffset] = len ;
3473            }
3474        }
3475        #endif
3476
3477        /* RSN : important information influence the result of creating an IBSS network */
3478        if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
3479        {
3480            u8_t frameType = ZM_WLAN_FRAME_TYPE_AUTH ;
3481            u8_t    rsn[64]=
3482            {
3483                        /* Element ID */
3484                        0x30,
3485                        /* Length */
3486                        0x14,
3487                        /* Version */
3488                        0x01, 0x00,
3489                        /* Group Cipher Suite, default=TKIP */
3490                        0x00, 0x0f, 0xac, 0x04,
3491                        /* Pairwise Cipher Suite Count */
3492                        0x01, 0x00,
3493                        /* Pairwise Cipher Suite, default=TKIP */
3494                        0x00, 0x0f, 0xac, 0x02,
3495                        /* Authentication and Key Management Suite Count */
3496                        0x01, 0x00,
3497                        /* Authentication type, default=PSK */
3498                        0x00, 0x0f, 0xac, 0x02,
3499                        /* RSN capability */
3500                        0x00, 0x00
3501            };
3502
3503            /* Overwrite Group Cipher Suite by AP's setting */
3504            zfMemoryCopy(rsn+4, zgWpa2AesOui, 4);
3505
3506            if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3507            {
3508                /* Overwrite Pairwise Cipher Suite by AES */
3509                zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
3510            }
3511
3512            // RSN element id
3513            wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_RSN_IE ;
3514
3515            // RSN length
3516            wd->sta.beaconFrameBody[offset++] = rsn[1] ;
3517
3518            // RSN information
3519            for(i=0; i<rsn[1]; i++)
3520                wd->sta.beaconFrameBody[offset++] = rsn[i+2] ;
3521
3522            zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
3523
3524#ifdef ZM_ENABLE_IBSS_WPA2PSK
3525            /* If not use RSNA , run traditional */
3526            zmw_enter_critical_section(dev);
3527            wd->sta.ibssWpa2Psk = 1;
3528            zmw_leave_critical_section(dev);
3529#endif
3530        }
3531
3532        #if 0
3533        /* HT Capabilities Info */
3534        {
3535            u8_t OUI[3] = { 0x0 , 0x90 , 0x4C } ;
3536
3537            wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_WPA_IE ;
3538
3539            wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Data.Length + 4 ;
3540
3541            for (i = 0; i < 3; i++)
3542            {
3543                wd->sta.beaconFrameBody[offset++] = OUI[i] ;
3544            }
3545
3546            wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Data.ElementID ;
3547
3548            for (i = 0; i < 26; i++)
3549            {
3550                wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Byte[i+2] ;
3551            }
3552        }
3553
3554        /* Extended HT Capabilities Info */
3555        {
3556            u8_t OUI[3] = { 0x0 , 0x90 , 0x4C } ;
3557
3558            wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_WPA_IE ;
3559
3560            wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Data.Length + 4 ;
3561
3562            for (i = 0; i < 3; i++)
3563            {
3564                wd->sta.beaconFrameBody[offset++] = OUI[i] ;
3565            }
3566
3567            wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Data.ElementID ;
3568
3569            for (i = 0; i < 22; i++)
3570            {
3571                wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Byte[i+2] ;
3572            }
3573        }
3574        #endif
3575
3576        wd->sta.beaconFrameBodySize = offset ;
3577
3578        if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3579        {
3580            wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3581        }
3582
3583        // 20070416 Let Create IBSS network could enter the zfwIbssPartnerNotify function
3584        // bssNotFound = FALSE ;
3585
3586        printk("The capability info 1 = %02x\n", wd->sta.capability[0]) ;
3587        printk("The capability info 2 = %02x\n", wd->sta.capability[1]) ;
3588        for(k=0; k<wd->sta.beaconFrameBodySize; k++)
3589        {
3590             printk("%02x ", wd->sta.beaconFrameBody[k]) ;
3591        }
3592        #if 0
3593        zmw_enter_critical_section(dev);
3594        zfMemoryCopy(event.bssid, (u8_t *)bssid, 6);
3595        zfMemoryCopy(event.peerMacAddr, (u8_t *)wd->macAddr, 6);
3596        zmw_leave_critical_section(dev);
3597        #endif
3598#endif
3599
3600        //zmw_enter_critical_section(dev);
3601        //wd->sta.ibssPartnerStatus = ZM_IBSS_PARTNER_LOST;
3602        //zmw_leave_critical_section(dev);
3603    }
3604    else
3605    {
3606        wd->sta.ibssBssIsCreator = 0;
3607    }
3608
3609connect_done:
3610    zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow);
3611    zfStaSendBeacon(dev); // Refresh Beacon content for ZD1211B HalPlus
3612    zfHpSetAtimWindow(dev, wd->sta.atimWindow);
3613
3614    // Start the IBSS timer to monitor for new stations
3615    zmw_enter_critical_section(dev);
3616    zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR);
3617    zmw_leave_critical_section(dev);
3618
3619
3620    if (wd->zfcbConnectNotify != NULL)
3621    {
3622        wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
3623    }
3624    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
3625    wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
3626
3627#ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION
3628    if ( !bssNotFound )
3629    {
3630        wd->sta.ibssDelayedInd = 1;
3631        zfMemoryCopy((u8_t *)&wd->sta.ibssDelayedIndEvent, (u8_t *)&event, sizeof(struct zsPartnerNotifyEvent));
3632    }
3633#else
3634    if ( !bssNotFound )
3635    {
3636        if (wd->zfcbIbssPartnerNotify != NULL)
3637        {
3638            wd->zfcbIbssPartnerNotify(dev, 1, &event);
3639        }
3640    }
3641#endif
3642
3643    return;
3644
3645retry_ibss:
3646    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
3647    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0);
3648    return;
3649}
3650
3651void zfStaProcessAtim(zdev_t* dev, zbuf_t* buf)
3652{
3653    zmw_get_wlan_dev(dev);
3654
3655    zm_debug_msg0("Receiving Atim window notification");
3656
3657    wd->sta.recvAtim = 1;
3658}
3659
3660static struct zsBssInfo* zfInfraFindAPToConnect(zdev_t* dev,
3661        struct zsBssInfo* candidateBss)
3662{
3663    struct zsBssInfo* pBssInfo;
3664    struct zsBssInfo* pNowBssInfo=NULL;
3665    u16_t i;
3666    u16_t ret, apWepStatus;
3667    u32_t k;
3668    u32_t channelFlags;
3669
3670    zmw_get_wlan_dev(dev);
3671    zmw_declare_for_critical_section();
3672
3673    zmw_enter_critical_section(dev);
3674
3675    pBssInfo = wd->sta.bssList.head;
3676
3677    for(i=0; i<wd->sta.bssList.bssCount; i++)
3678    {
3679        if ( pBssInfo->capability[0] & ZM_BIT_4 )
3680        {
3681            apWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
3682        }
3683        else
3684        {
3685            apWepStatus = ZM_ENCRYPTION_WEP_DISABLED;
3686        }
3687
3688        if ( ((zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid,
3689                               wd->sta.ssidLen))&&
3690              (wd->sta.ssidLen == pBssInfo->ssid[1]))||
3691             ((wd->sta.ssidLen == 0)&&
3692               /* connect to any BSS: AP's ans STA's WEP status must match */
3693              (wd->sta.wepStatus == apWepStatus )&&
3694              (pBssInfo->securityType != ZM_SECURITY_TYPE_WPA) ))
3695        {
3696            if ( wd->sta.ssidLen == 0 )
3697            {
3698                zm_debug_msg0("ANY BSS found");
3699            }
3700
3701            if ( ((wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED && apWepStatus == ZM_ENCRYPTION_WEP_ENABLED) ||
3702                 (wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED &&
3703                 (apWepStatus == ZM_ENCRYPTION_WEP_DISABLED && wd->sta.dropUnencryptedPkts == 1))) &&
3704                 (wd->sta.authMode >= ZM_AUTH_MODE_OPEN && wd->sta.authMode <= ZM_AUTH_MODE_AUTO) )
3705            {
3706                zm_debug_msg0("Privacy policy is inconsistent");
3707                pBssInfo = pBssInfo->next;
3708                continue;
3709            }
3710
3711            /* for WPA negative test */
3712            if ( !zfCheckAuthentication(dev, pBssInfo) )
3713            {
3714                pBssInfo = pBssInfo->next;
3715                continue;
3716            }
3717
3718            /* Check bssid */
3719            if (wd->sta.bDesiredBssid == TRUE)
3720            {
3721                for (k=0; k<6; k++)
3722                {
3723                    if (wd->sta.desiredBssid[k] != pBssInfo->bssid[k])
3724                    {
3725                        zm_msg0_mm(ZM_LV_1, "desired bssid not matched 1");
3726                        break;
3727                    }
3728                }
3729
3730                if (k != 6)
3731                {
3732                    zm_msg0_mm(ZM_LV_1, "desired bssid not matched 2");
3733                    pBssInfo = pBssInfo->next;
3734                    continue;
3735                }
3736            }
3737
3738            /* Check support mode */
3739            if (pBssInfo->frequency > 3000) {
3740                if (   (pBssInfo->EnableHT == 1)
3741                    || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3742                {
3743                    channelFlags = CHANNEL_A_HT;
3744                    if (pBssInfo->enableHT40 == 1) {
3745                        channelFlags |= CHANNEL_HT40;
3746                    }
3747                } else {
3748                    channelFlags = CHANNEL_A;
3749                }
3750            } else {
3751                if (   (pBssInfo->EnableHT == 1)
3752                    || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3753                {
3754                    channelFlags = CHANNEL_G_HT;
3755                    if(pBssInfo->enableHT40 == 1) {
3756                        channelFlags |= CHANNEL_HT40;
3757                    }
3758                } else {
3759                    if (pBssInfo->extSupportedRates[1] == 0) {
3760                        channelFlags = CHANNEL_B;
3761                    } else {
3762                        channelFlags = CHANNEL_G;
3763                    }
3764                }
3765            }
3766
3767            if (   ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0))
3768                || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1))
3769                || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2))
3770                || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) )
3771            {
3772                pBssInfo = pBssInfo->next;
3773                continue;
3774            }
3775
3776            /* Skip if AP in blocking list */
3777            if ((ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid)) == TRUE)
3778            {
3779                zm_msg0_mm(ZM_LV_0, "Candidate AP in blocking List, skip if there's stilla choice!");
3780                pNowBssInfo = pBssInfo;
3781                pBssInfo = pBssInfo->next;
3782                continue;
3783            }
3784
3785            if ( pBssInfo->capability[0] & ZM_BIT_0 )  // check if infra-BSS
3786            {
3787                    pNowBssInfo = pBssInfo;
3788                    wd->sta.apWmeCapability = pBssInfo->wmeSupport;
3789
3790
3791                    goto done;
3792            }
3793        }
3794
3795        pBssInfo = pBssInfo->next;
3796    }
3797
3798done:
3799    if (pNowBssInfo != NULL)
3800    {
3801        zfwMemoryCopy((void*)candidateBss, (void*)pNowBssInfo, sizeof(struct zsBssInfo));
3802        pNowBssInfo = candidateBss;
3803    }
3804
3805    zmw_leave_critical_section(dev);
3806
3807    return pNowBssInfo;
3808}
3809
3810
3811void zfInfraConnectNetwork(zdev_t* dev)
3812{
3813    struct zsBssInfo* pBssInfo;
3814    struct zsBssInfo* pNowBssInfo=NULL;
3815    struct zsBssInfo candidateBss;
3816    //u16_t i, j=100, quality=10000;
3817    //u8_t ret=FALSE, apWepStatus;
3818    u8_t ret=FALSE;
3819    u16_t k;
3820    u8_t density = ZM_MPDU_DENSITY_NONE;
3821
3822    zmw_get_wlan_dev(dev);
3823    zmw_declare_for_critical_section();
3824
3825    /* Reset bssNotFoundCount for Ad-Hoc:IBSS */
3826    /* Need review : IbssConn -> InfraConn -> IbssConn etc, flag/counter reset? */
3827    zmw_enter_critical_section(dev);
3828    wd->sta.bssNotFoundCount = 0;
3829    zmw_leave_critical_section(dev);
3830
3831    /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */
3832    zfUpdateDefaultQosParameter(dev, 0);
3833
3834    zfStaRefreshBlockList(dev, 0);
3835
3836    /* change state to CONNECTING and stop the channel scanning */
3837    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
3838    zfPowerSavingMgrWakeup(dev);
3839
3840    wd->sta.wmeConnected = 0;
3841    wd->sta.psMgr.tempWakeUp = 0;
3842    wd->sta.qosInfo = 0;
3843    zfQueueFlush(dev, wd->sta.uapsdQ);
3844
3845    wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
3846
3847    //Reorder BssList by RSSI--CWYang(+)
3848    zfBssInfoReorderList(dev);
3849
3850    pNowBssInfo = zfInfraFindAPToConnect(dev, &candidateBss);
3851
3852        if (wd->sta.SWEncryptEnable != 0)
3853        {
3854            if (wd->sta.bSafeMode == 0)
3855            {
3856                    zfStaDisableSWEncryption(dev);//Quickly reboot
3857            }
3858        }
3859    if ( pNowBssInfo != NULL )
3860    {
3861        //zm_assert(pNowBssInfo != NULL);
3862
3863        pBssInfo = pNowBssInfo;
3864        wd->sta.ssidLen = pBssInfo->ssid[1];
3865        zfMemoryCopy(wd->sta.ssid, &(pBssInfo->ssid[2]), pBssInfo->ssid[1]);
3866        wd->frequency = pBssInfo->frequency;
3867        //wd->sta.flagFreqChanging = 1;
3868
3869        //zfCoreSetFrequency(dev, wd->frequency);
3870        zfUpdateBssid(dev, pBssInfo->bssid);
3871        zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO);
3872        zfUpdateSupportRate(dev, pBssInfo->supportedRates);
3873        zfUpdateSupportRate(dev, pBssInfo->extSupportedRates);
3874
3875        wd->beaconInterval = pBssInfo->beaconInterval[0] +
3876                             (((u16_t) pBssInfo->beaconInterval[1]) << 8);
3877        if (wd->beaconInterval == 0)
3878        {
3879            wd->beaconInterval = 100;
3880        }
3881
3882        /* ESS bit on */
3883        wd->sta.capability[0] |= ZM_BIT_0;
3884        /* IBSS bit off */
3885        wd->sta.capability[0] &= ~ZM_BIT_1;
3886
3887        /* 11n AP flag */
3888        wd->sta.EnableHT = pBssInfo->EnableHT;
3889        wd->sta.SG40 = pBssInfo->SG40;
3890#ifdef ZM_ENABLE_CENC
3891        if ( pBssInfo->securityType == ZM_SECURITY_TYPE_CENC )
3892        {
3893            wd->sta.wmeEnabled = 0; //Disable WMM in CENC
3894            cencInit(dev);
3895            cencSetCENCMode(dev, NdisCENC_PSK);
3896            wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
3897            /* CENC */
3898            if ( pBssInfo->cencIe[1] != 0 )
3899            {
3900                //wd->sta.wepStatus = ZM_ENCRYPTION_CENC;
3901                //wd->sta.encryMode = ZM_CENC;
3902                zfwCencHandleBeaconProbrespon(dev, (u8_t *)&pBssInfo->cencIe,
3903                        (u8_t *)&pBssInfo->ssid, (u8_t *)&pBssInfo->macaddr);
3904                zfMemoryCopy(wd->sta.cencIe, pBssInfo->cencIe,
3905                        pBssInfo->cencIe[1]+2);
3906            }
3907            else
3908            {
3909                wd->sta.cencIe[1] = 0;
3910            }
3911        }
3912#endif //ZM_ENABLE_CENC
3913        if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA )
3914        {
3915            wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
3916
3917            if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP )
3918            {
3919                wd->sta.encryMode = ZM_TKIP;
3920
3921                /* Turn on software encryption/decryption for TKIP */
3922                if (wd->sta.EnableHT == 1)
3923                {
3924                    zfStaEnableSWEncryption(dev, (ZM_SW_TKIP_ENCRY_EN|ZM_SW_TKIP_DECRY_EN));
3925                }
3926
3927                /* Do not support TKIP in 11n mode */
3928                //wd->sta.EnableHT = 0;
3929                //pBssInfo->enableHT40 = 0;
3930            }
3931            else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3932            {
3933                wd->sta.encryMode = ZM_AES;
3934
3935                /* If AP supports HT mode */
3936                if (wd->sta.EnableHT)
3937                {
3938                    /* Set MPDU density to 8 us*/
3939                    density = ZM_MPDU_DENSITY_8US;
3940                }
3941            }
3942
3943            if ( pBssInfo->wpaIe[1] != 0 )
3944            {
3945                zfMemoryCopy(wd->sta.wpaIe, pBssInfo->wpaIe,
3946                             pBssInfo->wpaIe[1]+2);
3947            }
3948            else
3949            {
3950                wd->sta.wpaIe[1] = 0;
3951            }
3952
3953            if ( pBssInfo->rsnIe[1] != 0 )
3954            {
3955                zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe,
3956                             pBssInfo->rsnIe[1]+2);
3957            }
3958            else
3959            {
3960                wd->sta.rsnIe[1] = 0;
3961            }
3962        }
3963
3964
3965
3966        /* check preamble bit */
3967        wd->preambleTypeInUsed = wd->preambleType;
3968        if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO )
3969        {
3970            if (pBssInfo->capability[0] & ZM_BIT_5)
3971            {
3972                wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3973            }
3974            else
3975            {
3976                wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG;
3977            }
3978        }
3979
3980        if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3981        {
3982            wd->sta.capability[0] &= ~ZM_BIT_5;
3983        }
3984        else
3985        {
3986            wd->sta.capability[0] |= ZM_BIT_5;
3987        }
3988
3989        /* check 802.11n 40MHz Setting */
3990        if ((pBssInfo->enableHT40 == 1) &&
3991            ((pBssInfo->extChOffset == 1) || (pBssInfo->extChOffset == 3)))
3992        {
3993            wd->BandWidth40 = pBssInfo->enableHT40;
3994            wd->ExtOffset = pBssInfo->extChOffset;
3995        }
3996        else
3997        {
3998            wd->BandWidth40 = 0;
3999            wd->ExtOffset = 0;
4000        }
4001
4002        /* check 802.11H support bit */
4003
4004        /* check Owl Ap */
4005        if ( pBssInfo->athOwlAp & ZM_BIT_0 )
4006        {
4007            /* In this function, FW retry will be enable, ZM_MAC_REG_RETRY_MAX
4008               will be set to 0.
4009             */
4010            zfHpDisableHwRetry(dev);
4011            wd->sta.athOwlAp = 1;
4012            /* Set MPDU density to 8 us*/
4013            density = ZM_MPDU_DENSITY_8US;
4014        }
4015        else
4016        {
4017            /* In this function, FW retry will be disable, ZM_MAC_REG_RETRY_MAX
4018               will be set to 3.
4019             */
4020            zfHpEnableHwRetry(dev);
4021            wd->sta.athOwlAp = 0;
4022        }
4023        wd->reorder = 1;
4024
4025        /* Set MPDU density */
4026        zfHpSetMPDUDensity(dev, density);
4027
4028        /* check short slot time bit */
4029        if ( pBssInfo->capability[1] & ZM_BIT_2 )
4030        {
4031            wd->sta.capability[1] |= ZM_BIT_2;
4032        }
4033
4034        if ( pBssInfo->erp & ZM_BIT_1 )
4035        {
4036            //zm_debug_msg0("protection mode on");
4037            wd->sta.bProtectionMode = TRUE;
4038            zfHpSetSlotTime(dev, 0);
4039        }
4040        else
4041        {
4042            //zm_debug_msg0("protection mode off");
4043            wd->sta.bProtectionMode = FALSE;
4044            zfHpSetSlotTime(dev, 1);
4045        }
4046
4047        if (pBssInfo->marvelAp == 1)
4048        {
4049            wd->sta.enableDrvBA = 0;
4050            /*
4051             * 8701 : NetGear 3500 (MARVELL)
4052             * Downlink issue : set slottime to 20.
4053             */
4054            zfHpSetSlotTimeRegister(dev, 0);
4055        }
4056        else
4057        {
4058            wd->sta.enableDrvBA = 1;
4059
4060            /*
4061             * This is not good for here do reset slot time.
4062             * I think it should reset when leave MARVELL ap
4063             * or enter disconnect state etc.
4064             */
4065            zfHpSetSlotTimeRegister(dev, 1);
4066        }
4067
4068        //Store probe response frame body, for VISTA only
4069        wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12;
4070        if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
4071        {
4072            wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
4073        }
4074        for (k=0; k<8; k++)
4075        {
4076            wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k];
4077        }
4078        wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0];
4079        wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1];
4080        wd->sta.beaconFrameBody[10] = pBssInfo->capability[0];
4081        wd->sta.beaconFrameBody[11] = pBssInfo->capability[1];
4082        for (k=0; k<(wd->sta.beaconFrameBodySize - 12); k++)
4083        {
4084            wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k];
4085        }
4086
4087        if ( ( pBssInfo->capability[0] & ZM_BIT_4 )&&
4088             (( wd->sta.authMode == ZM_AUTH_MODE_OPEN )||
4089              ( wd->sta.authMode == ZM_AUTH_MODE_SHARED_KEY)||
4090              (wd->sta.authMode == ZM_AUTH_MODE_AUTO)) )
4091        {   /* privacy enabled */
4092
4093            if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED )
4094            {
4095                zm_debug_msg0("Adapter is no WEP, try to connect to WEP AP");
4096                ret = FALSE;
4097            }
4098
4099            /* Do not support WEP in 11n mode */
4100            if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED )
4101            {
4102                /* Turn on software encryption/decryption for WEP */
4103                if (wd->sta.EnableHT == 1)
4104                {
4105                    zfStaEnableSWEncryption(dev, (ZM_SW_WEP_ENCRY_EN|ZM_SW_WEP_DECRY_EN));
4106                }
4107
4108                //wd->sta.EnableHT = 0;
4109                //wd->BandWidth40 = 0;
4110                //wd->ExtOffset = 0;
4111            }
4112
4113            wd->sta.capability[0] |= ZM_BIT_4;
4114
4115            if ( wd->sta.authMode == ZM_AUTH_MODE_AUTO )
4116            { /* Try to use open and shared-key authehtication alternatively */
4117                if ( (wd->sta.connectTimeoutCount % 2) == 0 )
4118                    wd->sta.bIsSharedKey = 0;
4119                else
4120                    wd->sta.bIsSharedKey = 1;
4121            }
4122            else if ( wd->sta.authMode != ZM_AUTH_MODE_SHARED_KEY )
4123            {   /* open  or auto */
4124                //zfStaStartConnect(dev, 0);
4125                wd->sta.bIsSharedKey = 0;
4126            }
4127            else if ( wd->sta.authMode != ZM_AUTH_MODE_OPEN )
4128            {   /* shared key */
4129                //zfStaStartConnect(dev, 1) ;
4130                wd->sta.bIsSharedKey = 1;
4131            }
4132        }
4133        else
4134        {
4135            if ( (pBssInfo->securityType == ZM_SECURITY_TYPE_WPA)||
4136                 (pBssInfo->capability[0] & ZM_BIT_4) )
4137            {
4138                wd->sta.capability[0] |= ZM_BIT_4;
4139                /* initialize WPA related parameters */
4140            }
4141            else
4142            {
4143                wd->sta.capability[0] &= (~ZM_BIT_4);
4144            }
4145
4146            /* authentication with open system */
4147            //zfStaStartConnect(dev, 0);
4148            wd->sta.bIsSharedKey = 0;
4149        }
4150
4151        /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */
4152        /*
4153        if ( (pBssInfo->broadcomHTAp == 1)
4154             && (wd->sta.SWEncryptEnable != 0) )
4155        {
4156            zfHpSetTTSIFSTime(dev, 0xa);
4157        }
4158        else
4159        {
4160            zfHpSetTTSIFSTime(dev, 0x8);
4161        }
4162        */
4163    }
4164    else
4165    {
4166        zm_debug_msg0("Desired SSID not found");
4167        goto zlConnectFailed;
4168    }
4169
4170
4171    zfCoreSetFrequencyV2(dev, wd->frequency, zfStaStartConnectCb);
4172    return;
4173
4174zlConnectFailed:
4175    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0);
4176    return;
4177}
4178
4179u8_t zfCheckWPAAuth(zdev_t* dev, struct zsBssInfo* pBssInfo)
4180{
4181    u8_t   ret=TRUE;
4182    u8_t   pmkCount;
4183    u8_t   i;
4184    u16_t   encAlgoType = 0;
4185
4186    zmw_get_wlan_dev(dev);
4187
4188    if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP )
4189    {
4190        encAlgoType = ZM_TKIP;
4191    }
4192    else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4193    {
4194        encAlgoType = ZM_AES;
4195    }
4196
4197    switch(wd->sta.authMode)
4198    {
4199        case ZM_AUTH_MODE_WPA:
4200        case ZM_AUTH_MODE_WPAPSK:
4201            if ( pBssInfo->wpaIe[1] == 0 )
4202            {
4203                ret = FALSE;
4204                break;
4205            }
4206
4207            pmkCount = pBssInfo->wpaIe[12];
4208            for(i=0; i < pmkCount; i++)
4209            {
4210                if ( pBssInfo->wpaIe[17 + 4*i] == encAlgoType )
4211                {
4212                    ret = TRUE;
4213                    goto done;
4214                }
4215            }
4216
4217            ret = FALSE;
4218            break;
4219
4220        case ZM_AUTH_MODE_WPA2:
4221        case ZM_AUTH_MODE_WPA2PSK:
4222            if ( pBssInfo->rsnIe[1] == 0 )
4223            {
4224                ret = FALSE;
4225                break;
4226            }
4227
4228            pmkCount = pBssInfo->rsnIe[8];
4229            for(i=0; i < pmkCount; i++)
4230            {
4231                if ( pBssInfo->rsnIe[13 + 4*i] == encAlgoType )
4232                {
4233                    ret = TRUE;
4234                    goto done;
4235                }
4236            }
4237
4238            ret = FALSE;
4239            break;
4240    }
4241
4242done:
4243    return ret;
4244}
4245
4246u8_t zfCheckAuthentication(zdev_t* dev, struct zsBssInfo* pBssInfo)
4247{
4248    u8_t   ret=TRUE;
4249    u16_t  encAlgoType;
4250    u16_t UnicastCipherNum;
4251
4252    zmw_get_wlan_dev(dev);
4253
4254    /* Connecting to ANY has been checked */
4255    if ( wd->sta.ssidLen == 0 )
4256    {
4257        return ret;
4258    }
4259
4260
4261        switch(wd->sta.authMode)
4262        //switch(wd->ws.authMode)//Quickly reboot
4263    {
4264        case ZM_AUTH_MODE_WPA_AUTO:
4265        case ZM_AUTH_MODE_WPAPSK_AUTO:
4266            encAlgoType = 0;
4267            if(pBssInfo->rsnIe[1] != 0)
4268            {
4269                UnicastCipherNum = (pBssInfo->rsnIe[8]) +
4270                                   (pBssInfo->rsnIe[9] << 8);
4271
4272                /* If there is only one unicast cipher */
4273                if (UnicastCipherNum == 1)
4274                {
4275                    encAlgoType = pBssInfo->rsnIe[13];
4276                    //encAlgoType = pBssInfo->rsnIe[7];
4277                }
4278                else
4279                {
4280                    u16_t ii;
4281                    u16_t desiredCipher = 0;
4282                    u16_t IEOffSet = 13;
4283
4284                    /* Enumerate all the supported unicast cipher */
4285                    for (ii = 0; ii < UnicastCipherNum; ii++)
4286                    {
4287                        if (pBssInfo->rsnIe[IEOffSet+ii*4] > desiredCipher)
4288                        {
4289                            desiredCipher = pBssInfo->rsnIe[IEOffSet+ii*4];
4290                        }
4291                    }
4292
4293                    encAlgoType = desiredCipher;
4294                }
4295
4296                if ( encAlgoType == 0x02 )
4297                {
4298                            wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
4299
4300                            if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4301                    {
4302                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2;
4303                    }
4304                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4305                    {
4306                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK;
4307                    }
4308                }
4309                else if ( encAlgoType == 0x04 )
4310                {
4311                    wd->sta.wepStatus = ZM_ENCRYPTION_AES;
4312
4313                    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4314                    {
4315                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2;
4316                    }
4317                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4318                    {
4319                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK;
4320                    }
4321                }
4322                else
4323                {
4324                    ret = FALSE;
4325                }
4326            }
4327            else if(pBssInfo->wpaIe[1] != 0)
4328            {
4329                UnicastCipherNum = (pBssInfo->wpaIe[12]) +
4330                                   (pBssInfo->wpaIe[13] << 8);
4331
4332                /* If there is only one unicast cipher */
4333                if (UnicastCipherNum == 1)
4334                {
4335                    encAlgoType = pBssInfo->wpaIe[17];
4336                    //encAlgoType = pBssInfo->wpaIe[11];
4337                }
4338                else
4339                {
4340                    u16_t ii;
4341                    u16_t desiredCipher = 0;
4342                    u16_t IEOffSet = 17;
4343
4344                    /* Enumerate all the supported unicast cipher */
4345                    for (ii = 0; ii < UnicastCipherNum; ii++)
4346                    {
4347                        if (pBssInfo->wpaIe[IEOffSet+ii*4] > desiredCipher)
4348                        {
4349                            desiredCipher = pBssInfo->wpaIe[IEOffSet+ii*4];
4350                        }
4351                    }
4352
4353                    encAlgoType = desiredCipher;
4354                }
4355
4356                if ( encAlgoType == 0x02 )
4357                {
4358                            wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
4359
4360                            if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4361                    {
4362                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA;
4363                    }
4364                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4365                    {
4366                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK;
4367                    }
4368                }
4369                else if ( encAlgoType == 0x04 )
4370                {
4371                    wd->sta.wepStatus = ZM_ENCRYPTION_AES;
4372
4373                    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4374                    {
4375                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA;
4376                    }
4377                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4378                    {
4379                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK;
4380                    }
4381                }
4382                else
4383                {
4384                    ret = FALSE;
4385                }
4386
4387
4388            }
4389            else
4390            {
4391                ret = FALSE;
4392            }
4393
4394            break;
4395
4396        case ZM_AUTH_MODE_WPA:
4397        case ZM_AUTH_MODE_WPAPSK:
4398        case ZM_AUTH_MODE_WPA_NONE:
4399        case ZM_AUTH_MODE_WPA2:
4400        case ZM_AUTH_MODE_WPA2PSK:
4401            {
4402                if ( pBssInfo->securityType != ZM_SECURITY_TYPE_WPA )
4403                {
4404                    ret = FALSE;
4405                }
4406
4407                ret = zfCheckWPAAuth(dev, pBssInfo);
4408            }
4409            break;
4410
4411        case ZM_AUTH_MODE_OPEN:
4412        case ZM_AUTH_MODE_SHARED_KEY:
4413        case ZM_AUTH_MODE_AUTO:
4414            {
4415                if ( pBssInfo->wscIe[1] )
4416                {
4417                    // If the AP is a Jumpstart AP, it's ok!! Ray
4418                    break;
4419                }
4420                else if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA )
4421                {
4422                    ret = FALSE;
4423                }
4424            }
4425            break;
4426
4427        default:
4428            break;
4429    }
4430
4431    return ret;
4432}
4433
4434u8_t zfStaIsConnected(zdev_t* dev)
4435{
4436    zmw_get_wlan_dev(dev);
4437
4438    if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTED )
4439    {
4440        return TRUE;
4441    }
4442
4443    return FALSE;
4444}
4445
4446u8_t zfStaIsConnecting(zdev_t* dev)
4447{
4448    zmw_get_wlan_dev(dev);
4449
4450    if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTING )
4451    {
4452        return TRUE;
4453    }
4454
4455    return FALSE;
4456}
4457
4458u8_t zfStaIsDisconnect(zdev_t* dev)
4459{
4460    zmw_get_wlan_dev(dev);
4461
4462    if ( wd->sta.adapterState == ZM_STA_STATE_DISCONNECT )
4463    {
4464        return TRUE;
4465    }
4466
4467    return FALSE;
4468}
4469
4470u8_t zfChangeAdapterState(zdev_t* dev, u8_t newState)
4471{
4472    u8_t ret = TRUE;
4473
4474    zmw_get_wlan_dev(dev);
4475
4476    zmw_declare_for_critical_section();
4477
4478    //if ( newState == wd->sta.adapterState )
4479    //{
4480    //    return FALSE;
4481    //}
4482
4483    switch(newState)
4484    {
4485    case ZM_STA_STATE_DISCONNECT:
4486        zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT);
4487
4488        #if 1
4489            zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
4490        #else
4491            if ( wd->sta.bChannelScan )
4492            {
4493                /* stop the action of channel scanning */
4494                wd->sta.bChannelScan = FALSE;
4495                ret =  TRUE;
4496                break;
4497            }
4498        #endif
4499
4500        break;
4501    case ZM_STA_STATE_CONNECTING:
4502        #if 1
4503            zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
4504        #else
4505            if ( wd->sta.bChannelScan )
4506            {
4507                /* stop the action of channel scanning */
4508                wd->sta.bChannelScan = FALSE;
4509                ret =  TRUE;
4510                break;
4511            }
4512        #endif
4513
4514        break;
4515    case ZM_STA_STATE_CONNECTED:
4516        break;
4517    default:
4518        break;
4519    }
4520
4521    //if ( ret )
4522    //{
4523        zmw_enter_critical_section(dev);
4524        wd->sta.adapterState = newState;
4525        zmw_leave_critical_section(dev);
4526
4527        zm_debug_msg1("change adapter state = ", newState);
4528    //}
4529
4530    return ret;
4531}
4532
4533/************************************************************************/
4534/*                                                                      */
4535/*    FUNCTION DESCRIPTION                  zfStaMmAddIeSsid            */
4536/*      Add information element SSID to buffer.                         */
4537/*                                                                      */
4538/*    INPUTS                                                            */
4539/*      dev : device pointer                                            */
4540/*      buf : buffer to add information element                         */
4541/*      offset : add information element from this offset               */
4542/*                                                                      */
4543/*    OUTPUTS                                                           */
4544/*      buffer offset after adding information element                  */
4545/*                                                                      */
4546/*    AUTHOR                                                            */
4547/*      Ji-Huang Lee        ZyDAS Technology Corporation    2005.11     */
4548/*                                                                      */
4549/************************************************************************/
4550u16_t zfStaAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset)
4551{
4552    u16_t i;
4553
4554    zmw_get_wlan_dev(dev);
4555
4556    /* Element ID */
4557    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
4558
4559    /* Element Length */
4560    zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssidLen);
4561
4562    /* Information : SSID */
4563    for (i=0; i<wd->sta.ssidLen; i++)
4564    {
4565        zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssid[i]);
4566    }
4567
4568    return offset;
4569}
4570
4571/************************************************************************/
4572/*                                                                      */
4573/*    FUNCTION DESCRIPTION                  zfStaMmAddIeWpa             */
4574/*      Add information element SSID to buffer.                         */
4575/*                                                                      */
4576/*    INPUTS                                                            */
4577/*      dev : device pointer                                            */
4578/*      buf : buffer to add information element                         */
4579/*      offset : add information element from this offset               */
4580/*                                                                      */
4581/*    OUTPUTS                                                           */
4582/*      buffer offset after adding information element                  */
4583/*                                                                      */
4584/*    AUTHOR                                                            */
4585/*      Ji-Huang Lee        ZyDAS Technology Corporation    2006.01     */
4586/*                                                                      */
4587/************************************************************************/
4588u16_t zfStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType)
4589{
4590    u32_t  i;
4591    u8_t    ssn[64]={
4592                        /* Element ID */
4593                        0xdd,
4594                        /* Length */
4595                        0x18,
4596                        /* OUI type */
4597                        0x00, 0x50, 0xf2, 0x01,
4598                        /* Version */
4599                        0x01, 0x00,
4600                        /* Group Cipher Suite, default=TKIP */
4601                        0x00, 0x50, 0xf2, 0x02,
4602                        /* Pairwise Cipher Suite Count */
4603                        0x01, 0x00,
4604                        /* Pairwise Cipher Suite, default=TKIP */
4605                        0x00, 0x50, 0xf2, 0x02,
4606                        /* Authentication and Key Management Suite Count */
4607                        0x01, 0x00,
4608                        /* Authentication type, default=PSK */
4609                        0x00, 0x50, 0xf2, 0x02,
4610                        /* WPA capability */
4611                        0x00, 0x00
4612                    };
4613
4614    u8_t    rsn[64]={
4615                        /* Element ID */
4616                        0x30,
4617                        /* Length */
4618                        0x14,
4619                        /* Version */
4620                        0x01, 0x00,
4621                        /* Group Cipher Suite, default=TKIP */
4622                        0x00, 0x0f, 0xac, 0x02,
4623                        /* Pairwise Cipher Suite Count */
4624                        0x01, 0x00,
4625                        /* Pairwise Cipher Suite, default=TKIP */
4626                        0x00, 0x0f, 0xac, 0x02,
4627                        /* Authentication and Key Management Suite Count */
4628                        0x01, 0x00,
4629                        /* Authentication type, default=PSK */
4630                        0x00, 0x0f, 0xac, 0x02,
4631                        /* RSN capability */
4632                        0x00, 0x00
4633                    };
4634
4635    zmw_get_wlan_dev(dev);
4636
4637    if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPAPSK )
4638    {
4639        /* Overwrite Group Cipher Suite by AP's setting */
4640        zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4);
4641
4642        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4643        {
4644            /* Overwrite Pairwise Cipher Suite by AES */
4645            zfMemoryCopy(ssn+14, zgWpaAesOui, 4);
4646        }
4647
4648        zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2);
4649        zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2);
4650        offset += (ssn[1]+2);
4651    }
4652    else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA )
4653    {
4654        /* Overwrite Group Cipher Suite by AP's setting */
4655        zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4);
4656        /* Overwrite Key Management Suite by WPA-Radius */
4657        zfMemoryCopy(ssn+20, zgWpaRadiusOui, 4);
4658
4659        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4660        {
4661            /* Overwrite Pairwise Cipher Suite by AES */
4662            zfMemoryCopy(ssn+14, zgWpaAesOui, 4);
4663        }
4664
4665        zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2);
4666        zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2);
4667        offset += (ssn[1]+2);
4668    }
4669    else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2PSK )
4670    {
4671        /* Overwrite Group Cipher Suite by AP's setting */
4672        zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4);
4673
4674        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4675        {
4676            /* Overwrite Pairwise Cipher Suite by AES */
4677            zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
4678        }
4679
4680        if ( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ )
4681        {
4682            for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++)
4683            {
4684                if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid,
4685                                     (u8_t*) wd->sta.bssid, 6) )
4686                {
4687                    /* matched */
4688                    break;
4689                }
4690
4691                if ( i < wd->sta.pmkidInfo.bssidCount )
4692                {
4693                    // Fill PMKID Count in RSN information element
4694                    rsn[22] = 0x01;
4695                    rsn[23] = 0x00;
4696
4697                    // Fill PMKID in RSN information element
4698                    zfMemoryCopy(rsn+24,
4699                                 wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16);
4700                                         rsn[1] += 18;
4701                }
4702            }
4703        }
4704
4705        zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2);
4706        zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
4707        offset += (rsn[1]+2);
4708    }
4709    else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2 )
4710    {
4711        /* Overwrite Group Cipher Suite by AP's setting */
4712        zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4);
4713        /* Overwrite Key Management Suite by WPA2-Radius */
4714        zfMemoryCopy(rsn+16, zgWpa2RadiusOui, 4);
4715
4716        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4717        {
4718            /* Overwrite Pairwise Cipher Suite by AES */
4719            zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
4720        }
4721
4722        if (( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ || ( frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ )))
4723        {
4724
4725            if (wd->sta.pmkidInfo.bssidCount != 0) {
4726                // Fill PMKID Count in RSN information element
4727                rsn[22] = 1;
4728                rsn[23] = 0;
4729                /*
4730                 *  The caller is respnsible to give us the relevant PMKID.
4731                 *  We'll only accept 1 PMKID for now.
4732                 */
4733                for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++)
4734                {
4735                    if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, (u8_t*) wd->sta.bssid, 6) )
4736                    {
4737                        zfMemoryCopy(rsn+24, wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16);
4738                        break;
4739                    }
4740                }
4741                rsn[1] += 18;
4742            }
4743
4744        }
4745
4746        zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2);
4747        zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
4748        offset += (rsn[1]+2);
4749    }
4750
4751    return offset;
4752}
4753
4754/************************************************************************/
4755/*                                                                      */
4756/*    FUNCTION DESCRIPTION                  zfStaAddIeIbss              */
4757/*      Add information element IBSS parameter to buffer.               */
4758/*                                                                      */
4759/*    INPUTS                                                            */
4760/*      dev : device pointer                                            */
4761/*      buf : buffer to add information element                         */
4762/*      offset : add information element from this offset               */
4763/*                                                                      */
4764/*    OUTPUTS                                                           */
4765/*      buffer offset after adding information element                  */
4766/*                                                                      */
4767/*    AUTHOR                                                            */
4768/*      Ji-Huang Lee        ZyDAS Technology Corporation    2005.12     */
4769/*                                                                      */
4770/************************************************************************/
4771u16_t zfStaAddIeIbss(zdev_t* dev, zbuf_t* buf, u16_t offset)
4772{
4773    zmw_get_wlan_dev(dev);
4774
4775    /* Element ID */
4776    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_IBSS);
4777
4778    /* Element Length */
4779    zmw_tx_buf_writeb(dev, buf, offset++, 2);
4780
4781    /* ATIM window */
4782    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.atimWindow);
4783    offset += 2;
4784
4785    return offset;
4786}
4787
4788
4789
4790/************************************************************************/
4791/*                                                                      */
4792/*    FUNCTION DESCRIPTION                  zfStaAddIeWmeInfo           */
4793/*      Add WME Information Element to buffer.                          */
4794/*                                                                      */
4795/*    INPUTS                                                            */
4796/*      dev : device pointer                                            */
4797/*      buf : buffer to add information element                         */
4798/*      offset : add information element from this offset               */
4799/*                                                                      */
4800/*    OUTPUTS                                                           */
4801/*      buffer offset after adding information element                  */
4802/*                                                                      */
4803/*    AUTHOR                                                            */
4804/*      Stephen Chen        ZyDAS Technology Corporation    2006.6      */
4805/*                                                                      */
4806/************************************************************************/
4807u16_t zfStaAddIeWmeInfo(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t qosInfo)
4808{
4809    /* Element ID */
4810    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
4811
4812    /* Element Length */
4813    zmw_tx_buf_writeb(dev, buf, offset++, 7);
4814
4815    /* OUI */
4816    zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
4817    zmw_tx_buf_writeb(dev, buf, offset++, 0x50);
4818    zmw_tx_buf_writeb(dev, buf, offset++, 0xF2);
4819    zmw_tx_buf_writeb(dev, buf, offset++, 0x02);
4820    zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
4821    zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
4822
4823    /* QoS Info */
4824    zmw_tx_buf_writeb(dev, buf, offset++, qosInfo);
4825
4826    return offset;
4827}
4828
4829/************************************************************************/
4830/*                                                                      */
4831/*    FUNCTION DESCRIPTION                  zfStaAddIePowerCap          */
4832/*      Add information element Power capability to buffer.             */
4833/*                                                                      */
4834/*    INPUTS                                                            */
4835/*      dev : device pointer                                            */
4836/*      buf : buffer to add information element                         */
4837/*      offset : add information element from this offset               */
4838/*                                                                      */
4839/*    OUTPUTS                                                           */
4840/*      buffer offset after adding information element                  */
4841/*                                                                      */
4842/*    AUTHOR                                                            */
4843/*      Sharon                                            2007.12       */
4844/*                                                                      */
4845/************************************************************************/
4846u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset)
4847{
4848    u8_t MaxTxPower;
4849    u8_t MinTxPower;
4850
4851    zmw_get_wlan_dev(dev);
4852
4853    /* Element ID */
4854    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY);
4855
4856    /* Element Length */
4857    zmw_tx_buf_writeb(dev, buf, offset++, 2);
4858
4859    MinTxPower = (u8_t)(zfHpGetMinTxPower(dev)/2);
4860    MaxTxPower = (u8_t)(zfHpGetMaxTxPower(dev)/2);
4861
4862    /* Min Transmit Power Cap */
4863    zmw_tx_buf_writeh(dev, buf, offset++, MinTxPower);
4864
4865    /* Max Transmit Power Cap */
4866    zmw_tx_buf_writeh(dev, buf, offset++, MaxTxPower);
4867
4868    return offset;
4869}
4870/************************************************************************/
4871/*                                                                      */
4872/*    FUNCTION DESCRIPTION                  zfStaAddIeSupportCh              */
4873/*      Add information element supported channels to buffer.               */
4874/*                                                                      */
4875/*    INPUTS                                                            */
4876/*      dev : device pointer                                            */
4877/*      buf : buffer to add information element                         */
4878/*      offset : add information element from this offset               */
4879/*                                                                      */
4880/*    OUTPUTS                                                           */
4881/*      buffer offset after adding information element                  */
4882/*                                                                      */
4883/*    AUTHOR                                                            */
4884/*      Sharon            2007.12     */
4885/*                                                                      */
4886/************************************************************************/
4887u16_t zfStaAddIeSupportCh(zdev_t* dev, zbuf_t* buf, u16_t offset)
4888{
4889
4890    u8_t   i;
4891    u16_t  count_24G = 0;
4892    u16_t  count_5G = 0;
4893    u16_t  channelNum;
4894    u8_t   length;
4895
4896    zmw_get_wlan_dev(dev);
4897
4898    zmw_declare_for_critical_section();
4899    zmw_enter_critical_section(dev);
4900
4901    for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
4902    {
4903        if (wd->regulationTable.allowChannel[i].channel < 3000)
4904        { // 2.4Hz
4905            count_24G++;
4906        }
4907        else
4908        { // 5GHz
4909            count_5G++;
4910        }
4911    }
4912
4913    length = (u8_t)(count_5G * 2 + 2); //5G fill by pair, 2,4G (continuous channels) fill 2 bytes
4914
4915    /* Element ID */
4916    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SUPPORTED_CHANNELS );
4917
4918    /* Element Length */
4919    zmw_tx_buf_writeb(dev, buf, offset++, length);
4920
4921    // 2.4GHz (continuous channels)
4922    /* First channel number */
4923    zmw_tx_buf_writeh(dev, buf, offset++, 1); //Start from channle 1
4924    /* Number of channels */
4925    zmw_tx_buf_writeh(dev, buf, offset++, count_24G);
4926
4927    for (i = 0; i < wd->regulationTable.allowChannelCnt ; i++)
4928    {
4929        if (wd->regulationTable.allowChannel[i].channel > 4000 && wd->regulationTable.allowChannel[i].channel < 5000)
4930        { // 5GHz 4000 -5000Mhz
4931            channelNum = (wd->regulationTable.allowChannel[i].channel-4000)/5;
4932            /* First channel number */
4933            zmw_tx_buf_writeh(dev, buf, offset++, channelNum);
4934            /* Number of channels */
4935            zmw_tx_buf_writeh(dev, buf, offset++, 1);
4936        }
4937        else if (wd->regulationTable.allowChannel[i].channel >= 5000)
4938        { // 5GHz >5000Mhz
4939            channelNum = (wd->regulationTable.allowChannel[i].channel-5000)/5;
4940            /* First channel number */
4941            zmw_tx_buf_writeh(dev, buf, offset++, channelNum);
4942            /* Number of channels */
4943            zmw_tx_buf_writeh(dev, buf, offset++, 1);
4944        }
4945    }
4946   zmw_leave_critical_section(dev);
4947
4948    return offset;
4949}
4950
4951void zfStaStartConnectCb(zdev_t* dev)
4952{
4953    zmw_get_wlan_dev(dev);
4954
4955    zfStaStartConnect(dev, wd->sta.bIsSharedKey);
4956}
4957
4958void zfStaStartConnect(zdev_t* dev, u8_t bIsSharedKey)
4959{
4960    u32_t p1, p2;
4961    u8_t newConnState;
4962
4963    zmw_get_wlan_dev(dev);
4964    zmw_declare_for_critical_section();
4965
4966    /* p1_low = algorithm number, p1_high = transaction sequence number */
4967    if ( bIsSharedKey )
4968    {
4969        //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_1;
4970        newConnState = ZM_STA_CONN_STATE_AUTH_SHARE_1;
4971        zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_SHARE_1");
4972        p1 = ZM_AUTH_ALGO_SHARED_KEY;
4973    }
4974    else
4975    {
4976        //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_OPEN;
4977        newConnState = ZM_STA_CONN_STATE_AUTH_OPEN;
4978        zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_OPEN");
4979        if( wd->sta.leapEnabled )
4980            p1 = ZM_AUTH_ALGO_LEAP;
4981        else
4982            p1 = ZM_AUTH_ALGO_OPEN_SYSTEM;
4983    }
4984
4985    /* status code */
4986    p2 = 0x0;
4987
4988    zmw_enter_critical_section(dev);
4989    wd->sta.connectTimer = wd->tick;
4990    wd->sta.connectState = newConnState;
4991    zmw_leave_critical_section(dev);
4992
4993    /* send the 1st authentication frame */
4994    zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, wd->sta.bssid, p1, p2, 0);
4995
4996    return;
4997}
4998
4999void zfSendNullData(zdev_t* dev, u8_t type)
5000{
5001    zbuf_t* buf;
5002    //u16_t addrTblSize;
5003    //struct zsAddrTbl addrTbl;
5004    u16_t err;
5005    u16_t hlen;
5006    u16_t header[(34+8+1)/2];
5007    u16_t bcastAddr[3] = {0xffff,0xffff,0xffff};
5008    u16_t *dstAddr;
5009
5010    zmw_get_wlan_dev(dev);
5011
5012    if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
5013    {
5014        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
5015        return;
5016    }
5017
5018    zfwBufSetSize(dev, buf, 0);
5019
5020    //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
5021
5022    if ( wd->wlanMode == ZM_MODE_IBSS)
5023    {
5024        dstAddr = bcastAddr;
5025    }
5026    else
5027    {
5028        dstAddr = wd->sta.bssid;
5029    }
5030
5031    if (wd->sta.wmeConnected != 0)
5032    {
5033        /* If connect to a WMM AP, Send QoS Null data */
5034        hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_QOS_NULL, dstAddr, header, 0, buf, 0, 0);
5035    }
5036    else
5037    {
5038        hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_NULL, dstAddr, header, 0, buf, 0, 0);
5039    }
5040
5041    if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
5042    {
5043        header[4] |= 0x0100; //TODS bit
5044    }
5045
5046    if ( type == 1 )
5047    {
5048        header[4] |= 0x1000;
5049    }
5050
5051    /* Get buffer DMA address */
5052    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
5053    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
5054    //{
5055    //    goto zlError;
5056    //}
5057
5058    /*increase unicast frame counter*/
5059    wd->commTally.txUnicastFrm++;
5060
5061    if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
5062            ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
5063    {
5064        goto zlError;
5065    }
5066
5067
5068    return;
5069
5070zlError:
5071
5072    zfwBufFree(dev, buf, 0);
5073    return;
5074
5075}
5076
5077void zfSendPSPoll(zdev_t* dev)
5078{
5079    zbuf_t* buf;
5080    //u16_t addrTblSize;
5081    //struct zsAddrTbl addrTbl;
5082    u16_t err;
5083    u16_t hlen;
5084    u16_t header[(8+24+1)/2];
5085
5086    zmw_get_wlan_dev(dev);
5087
5088    if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
5089    {
5090        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
5091        return;
5092    }
5093
5094    zfwBufSetSize(dev, buf, 0);
5095
5096    //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
5097
5098    zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_PSPOLL, wd->sta.bssid, header, 0, buf, 0, 0);
5099
5100    header[0] = 20;
5101    header[4] |= 0x1000;
5102    header[5] = wd->sta.aid | 0xc000; //Both bit-14 and bit-15 are 1
5103    hlen = 16 + 8;
5104
5105    /* Get buffer DMA address */
5106    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
5107    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
5108    //{
5109    //    goto zlError;
5110    //}
5111
5112    if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
5113            ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
5114    {
5115        goto zlError;
5116    }
5117
5118    return;
5119
5120zlError:
5121
5122    zfwBufFree(dev, buf, 0);
5123    return;
5124
5125}
5126
5127void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap)
5128{
5129    zbuf_t* buf;
5130    //u16_t addrTblSize;
5131    //struct zsAddrTbl addrTbl;
5132    u16_t err;
5133    u16_t hlen;
5134    u16_t header[(8+24+1)/2];
5135    u16_t i, offset = 0;
5136
5137    zmw_get_wlan_dev(dev);
5138
5139    if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
5140    {
5141        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
5142        return;
5143    }
5144
5145    zfwBufSetSize(dev, buf, 12); // 28 = FC 2 + DU 2 + RA 6 + TA 6 + BAC 2 + SEQ 2 + BitMap 8
5146                                 // 12 = BAC 2 + SEQ 2 + BitMap 8
5147
5148    //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
5149
5150    zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_BA, wd->sta.bssid, header, 0, buf, 0, 0);
5151
5152    header[0] = 32; /* MAC header 16 + BA control 2 + BA info 10 + FCS 4*/
5153    header[1] = 0x4;  /* No ACK */
5154
5155    /* send by OFDM 6M */
5156    header[2] = (u16_t)(zcRateToPhyCtrl[4] & 0xffff);
5157    header[3] = (u16_t)(zcRateToPhyCtrl[4]>>16) & 0xffff;
5158
5159    hlen = 16 + 8;  /* MAC header 16 + control 8*/
5160    offset = 0;
5161    zmw_tx_buf_writeh(dev, buf, offset, 0x05); /*compressed bitmap on*/
5162    offset+=2;
5163    zmw_tx_buf_writeh(dev, buf, offset, start_seq);
5164    offset+=2;
5165
5166    for (i=0; i<8; i++) {
5167        zmw_tx_buf_writeb(dev, buf, offset, bitmap[i]);
5168        offset++;
5169    }
5170
5171    if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
5172            ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
5173    {
5174        goto zlError;
5175    }
5176
5177    return;
5178
5179zlError:
5180
5181    zfwBufFree(dev, buf, 0);
5182    return;
5183
5184}
5185
5186void zfStaGetTxRate(zdev_t* dev, u16_t* macAddr, u32_t* phyCtrl,
5187        u16_t* rcProbingFlag)
5188{
5189    u8_t   addr[6], i;
5190    u8_t   rate;
5191    zmw_get_wlan_dev(dev);
5192    zmw_declare_for_critical_section();
5193
5194    ZM_MAC_WORD_TO_BYTE(macAddr, addr);
5195    *phyCtrl = 0;
5196
5197    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
5198    {
5199        zmw_enter_critical_section(dev);
5200        rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[0].rcCell, rcProbingFlag);
5201//#ifdef ZM_FB50
5202        //rate = 27;
5203//#endif
5204        *phyCtrl = zcRateToPhyCtrl[rate];
5205        zmw_leave_critical_section(dev);
5206    }
5207    else
5208    {
5209        zmw_enter_critical_section(dev);
5210        for(i=0; i<wd->sta.oppositeCount; i++)
5211        {
5212            if ( addr[0] && 0x01 == 1 ) // The default beacon transmitted rate is CCK and 1 Mbps , but the a mode should use
5213                                        // OFDM modulation and 6Mbps to transmit beacon.
5214            {
5215                //rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag);
5216                rate = wd->sta.oppositeInfo[i].rcCell.operationRateSet[0];
5217                *phyCtrl = zcRateToPhyCtrl[rate];
5218                break;
5219            }
5220            else if ( zfMemoryIsEqual(addr, wd->sta.oppositeInfo[i].macAddr, 6) )
5221            {
5222                rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag);
5223                *phyCtrl = zcRateToPhyCtrl[rate];
5224                break;
5225            }
5226        }
5227        zmw_leave_critical_section(dev);
5228    }
5229
5230    return;
5231}
5232
5233struct zsMicVar* zfStaGetRxMicKey(zdev_t* dev, zbuf_t* buf)
5234{
5235    u8_t keyIndex;
5236    u8_t da0;
5237
5238    zmw_get_wlan_dev(dev);
5239
5240    /* if need not check MIC, return NULL */
5241    if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
5242         (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5243    {
5244        return NULL;
5245    }
5246
5247    da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5248
5249    if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80)
5250        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/
5251    else
5252        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/
5253    keyIndex = (keyIndex & 0xc0) >> 6;
5254
5255    return (&wd->sta.rxMicKey[keyIndex]);
5256}
5257
5258struct zsMicVar* zfStaGetTxMicKey(zdev_t* dev, zbuf_t* buf)
5259{
5260    zmw_get_wlan_dev(dev);
5261
5262    /* if need not check MIC, return NULL */
5263    //if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
5264    //     (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5265    if ( (wd->sta.encryMode != ZM_TKIP) || (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5266    {
5267        return NULL;
5268    }
5269
5270    return (&wd->sta.txMicKey);
5271}
5272
5273u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf)
5274{
5275    u8_t   frameType, frameCtrl;
5276    u8_t   da0;
5277    //u16_t  sa[3];
5278    u16_t  ret;
5279    u16_t  i;
5280    //u8_t    sa0;
5281
5282    zmw_get_wlan_dev(dev);
5283
5284    frameType = zmw_rx_buf_readb(dev, buf, 0);
5285    da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5286    //sa0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
5287
5288    if ( (!zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) )
5289    {
5290        return ZM_ERR_DATA_BEFORE_CONNECTED;
5291    }
5292
5293
5294    if ( (zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) )
5295    {
5296        /* check BSSID */
5297        if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
5298        {
5299            /* Big Endian and Little Endian Compatibility */
5300            u16_t mac[3];
5301            mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]);
5302            mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]);
5303            mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]);
5304            if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac,
5305                                       ZM_WLAN_HEADER_A2_OFFSET, 6) )
5306            {
5307/*We will get lots of garbage data, especially in AES mode.*/
5308/*To avoid sending too many deauthentication frames in STA mode, mark it.*/
5309#if 0
5310                /* If unicast frame, send deauth to the transmitter */
5311                if (( da0 & 0x01 ) == 0)
5312                {
5313                    for (i=0; i<3; i++)
5314                    {
5315                        sa[i] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+(i*2));
5316                    }
5317                                        /* If mutilcast address, don't send deauthentication*/
5318                                        if (( sa0 & 0x01 ) == 0)
5319                                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, sa, 7, 0, 0);
5320                }
5321#endif
5322                return ZM_ERR_DATA_BSSID_NOT_MATCHED;
5323            }
5324        }
5325        else if ( wd->wlanMode == ZM_MODE_IBSS )
5326        {
5327            /* Big Endian and Little Endian Compatibility */
5328            u16_t mac[3];
5329            mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]);
5330            mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]);
5331            mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]);
5332            if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac,
5333                                       ZM_WLAN_HEADER_A3_OFFSET, 6) )
5334            {
5335                return ZM_ERR_DATA_BSSID_NOT_MATCHED;
5336            }
5337        }
5338
5339        frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
5340
5341        /* check security bit */
5342        if ( wd->sta.dropUnencryptedPkts &&
5343             (wd->sta.wepStatus != ZM_ENCRYPTION_WEP_DISABLED )&&
5344             ( !(frameCtrl & ZM_BIT_6) ) )
5345        {   /* security on, but got data without encryption */
5346
5347            #if 1
5348            ret = ZM_ERR_DATA_NOT_ENCRYPTED;
5349            if ( wd->sta.pStaRxSecurityCheckCb != NULL )
5350            {
5351                ret = wd->sta.pStaRxSecurityCheckCb(dev, buf);
5352            }
5353            else
5354            {
5355                ret = ZM_ERR_DATA_NOT_ENCRYPTED;
5356            }
5357            if (ret == ZM_ERR_DATA_NOT_ENCRYPTED)
5358            {
5359                wd->commTally.swRxDropUnencryptedCount++;
5360            }
5361            return ret;
5362            #else
5363            if ( (wd->sta.wepStatus != ZM_ENCRYPTION_TKIP)&&
5364                 (wd->sta.wepStatus != ZM_ENCRYPTION_AES) )
5365            {
5366                return ZM_ERR_DATA_NOT_ENCRYPTED;
5367            }
5368            #endif
5369        }
5370    }
5371
5372    return ZM_SUCCESS;
5373}
5374
5375void zfStaMicFailureHandling(zdev_t* dev, zbuf_t* buf)
5376{
5377    u8_t   da0;
5378    u8_t   micNotify = 1;
5379
5380    zmw_get_wlan_dev(dev);
5381
5382    zmw_declare_for_critical_section();
5383
5384    if ( wd->sta.wpaState <  ZM_STA_WPA_STATE_PK_OK )
5385    {
5386        return;
5387    }
5388
5389    zmw_enter_critical_section(dev);
5390
5391    wd->sta.cmMicFailureCount++;
5392
5393    if ( wd->sta.cmMicFailureCount == 1 )
5394    {
5395        zm_debug_msg0("get the first MIC failure");
5396        //zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT);
5397
5398        /* Timer Resolution on WinXP is 15/16 ms  */
5399        /* Decrease Time offset for <XP> Counter Measure */
5400        zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT - ZM_TICK_CM_TIMEOUT_OFFSET);
5401    }
5402    else if ( wd->sta.cmMicFailureCount == 2 )
5403    {
5404        zm_debug_msg0("get the second MIC failure");
5405        /* reserve 2 second for OS to send MIC failure report to AP */
5406        wd->sta.cmDisallowSsidLength = wd->sta.ssidLen;
5407        zfMemoryCopy(wd->sta.cmDisallowSsid, wd->sta.ssid, wd->sta.ssidLen);
5408        //wd->sta.cmMicFailureCount = 0;
5409        zfTimerCancel(dev, ZM_EVENT_CM_TIMER);
5410        //zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT);
5411
5412        /* Timer Resolution on WinXP is 15/16 ms  */
5413        /* Decrease Time offset for <XP> Counter Measure */
5414        zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT - ZM_TICK_CM_DISCONNECT_OFFSET);
5415    }
5416    else
5417    {
5418        micNotify = 0;
5419    }
5420
5421    zmw_leave_critical_section(dev);
5422
5423    if (micNotify == 1)
5424    {
5425        da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5426        if ( da0 & 0x01 )
5427        {
5428            if (wd->zfcbMicFailureNotify != NULL)
5429            {
5430                wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_GROUP_ERROR);
5431            }
5432        }
5433        else
5434        {
5435            if (wd->zfcbMicFailureNotify != NULL)
5436            {
5437                wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_PAIRWISE_ERROR);
5438            }
5439        }
5440    }
5441}
5442
5443
5444u8_t zfStaBlockWlanScan(zdev_t* dev)
5445{
5446    u8_t   ret=FALSE;
5447
5448    zmw_get_wlan_dev(dev);
5449
5450    if ( wd->sta.bChannelScan )
5451    {
5452        return TRUE;
5453    }
5454
5455    return ret;
5456}
5457
5458void zfStaResetStatus(zdev_t* dev, u8_t bInit)
5459{
5460    u8_t   i;
5461
5462    zmw_get_wlan_dev(dev);
5463
5464    zfHpDisableBeacon(dev);
5465
5466    wd->dtim = 1;
5467    wd->sta.capability[0] = 0x01;
5468    wd->sta.capability[1] = 0x00;
5469    /* 802.11h */
5470    if (wd->sta.DFSEnable || wd->sta.TPCEnable)
5471        wd->sta.capability[1] |= ZM_BIT_0;
5472
5473    /* release queued packets */
5474    for(i=0; i<wd->sta.ibssPSDataCount; i++)
5475    {
5476        zfwBufFree(dev, wd->sta.ibssPSDataQueue[i], 0);
5477    }
5478
5479    for(i=0; i<wd->sta.staPSDataCount; i++)
5480    {
5481        zfwBufFree(dev, wd->sta.staPSDataQueue[i], 0);
5482    }
5483
5484    wd->sta.ibssPSDataCount = 0;
5485    wd->sta.staPSDataCount = 0;
5486    zfZeroMemory((u8_t*) &wd->sta.staPSList, sizeof(struct zsStaPSList));
5487
5488    wd->sta.wmeConnected = 0;
5489    wd->sta.psMgr.tempWakeUp = 0;
5490    wd->sta.qosInfo = 0;
5491    zfQueueFlush(dev, wd->sta.uapsdQ);
5492
5493    return;
5494
5495}
5496
5497void zfStaIbssMonitoring(zdev_t* dev, u8_t reset)
5498{
5499    u16_t i;
5500    u16_t oppositeCount;
5501    struct zsPartnerNotifyEvent event;
5502
5503    zmw_get_wlan_dev(dev);
5504
5505    zmw_declare_for_critical_section();
5506
5507    //zm_debug_msg1("zfStaIbssMonitoring %d", wd->sta.oppositeCount);
5508
5509    zmw_enter_critical_section(dev);
5510
5511    if ( wd->sta.oppositeCount == 0 )
5512    {
5513        goto done;
5514    }
5515
5516    if ( wd->sta.bChannelScan )
5517    {
5518        goto done;
5519    }
5520
5521    oppositeCount = wd->sta.oppositeCount;
5522
5523    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
5524    {
5525        if ( oppositeCount == 0 )
5526        {
5527            break;
5528        }
5529
5530        if ( reset )
5531        {
5532            wd->sta.oppositeInfo[i].valid = 0;
5533        }
5534
5535        if ( wd->sta.oppositeInfo[i].valid == 0 )
5536        {
5537            continue;
5538        }
5539
5540        oppositeCount--;
5541
5542        if ( wd->sta.oppositeInfo[i].aliveCounter )
5543        {
5544            zm_debug_msg1("Setting alive to ", wd->sta.oppositeInfo[i].aliveCounter);
5545
5546            zmw_leave_critical_section(dev);
5547
5548            if ( wd->sta.oppositeInfo[i].aliveCounter != ZM_IBSS_PEER_ALIVE_COUNTER )
5549            {
5550                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ,
5551                              (u16_t*)wd->sta.oppositeInfo[i].macAddr, 1, 0, 0);
5552            }
5553
5554            zmw_enter_critical_section(dev);
5555            wd->sta.oppositeInfo[i].aliveCounter--;
5556        }
5557        else
5558        {
5559            zm_debug_msg0("zfStaIbssMonitoring remove the peer station");
5560            zfMemoryCopy(event.bssid, (u8_t *)(wd->sta.bssid), 6);
5561            zfMemoryCopy(event.peerMacAddr, wd->sta.oppositeInfo[i].macAddr, 6);
5562
5563            wd->sta.oppositeInfo[i].valid = 0;
5564            wd->sta.oppositeCount--;
5565            if (wd->zfcbIbssPartnerNotify != NULL)
5566            {
5567                zmw_leave_critical_section(dev);
5568                wd->zfcbIbssPartnerNotify(dev, 0, &event);
5569                zmw_enter_critical_section(dev);
5570            }
5571        }
5572    }
5573
5574done:
5575    if ( reset == 0 )
5576    {
5577        zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR);
5578    }
5579
5580    zmw_leave_critical_section(dev);
5581}
5582
5583void zfInitPartnerNotifyEvent(zdev_t* dev, zbuf_t* buf, struct zsPartnerNotifyEvent *event)
5584{
5585    u16_t  *peerMacAddr;
5586
5587    zmw_get_wlan_dev(dev);
5588
5589    peerMacAddr = (u16_t *)event->peerMacAddr;
5590
5591    zfMemoryCopy(event->bssid, (u8_t *)(wd->sta.bssid), 6);
5592    peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
5593    peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 2);
5594    peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 4);
5595}
5596
5597void zfStaInitOppositeInfo(zdev_t* dev)
5598{
5599    int i;
5600
5601    zmw_get_wlan_dev(dev);
5602
5603    for(i=0; i<ZM_MAX_OPPOSITE_COUNT; i++)
5604    {
5605        wd->sta.oppositeInfo[i].valid = 0;
5606        wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
5607    }
5608}
5609#ifdef ZM_ENABLE_CENC
5610u16_t zfStaAddIeCenc(zdev_t* dev, zbuf_t* buf, u16_t offset)
5611{
5612    zmw_get_wlan_dev(dev);
5613
5614    if (wd->sta.cencIe[1] != 0)
5615    {
5616        zfCopyToIntTxBuffer(dev, buf, wd->sta.cencIe, offset, wd->sta.cencIe[1]+2);
5617        offset += (wd->sta.cencIe[1]+2);
5618    }
5619    return offset;
5620}
5621#endif //ZM_ENABLE_CENC
5622u16_t zfStaProcessAction(zdev_t* dev, zbuf_t* buf)
5623{
5624    u8_t category, actionDetails;
5625    zmw_get_wlan_dev(dev);
5626
5627    category = zmw_rx_buf_readb(dev, buf, 24);
5628    actionDetails = zmw_rx_buf_readb(dev, buf, 25);
5629    switch (category)
5630    {
5631        case 0:         //Spectrum Management
5632                switch(actionDetails)
5633                {
5634                        case 0:                 //Measurement Request
5635                                break;
5636                        case 1:                 //Measurement Report
5637                                //ProcessActionSpectrumFrame_MeasurementReport(Adapter,pActionBody+3);
5638                                break;
5639                        case 2:                 //TPC request
5640                    //if (wd->sta.TPCEnable)
5641                    //    zfStaUpdateDot11HTPC(dev, buf);
5642                                break;
5643                        case 3:                 //TPC report
5644                    //if (wd->sta.TPCEnable)
5645                    //    zfStaUpdateDot11HTPC(dev, buf);
5646                                break;
5647                        case 4:                 //Channel Switch Announcement
5648                    if (wd->sta.DFSEnable)
5649                        zfStaUpdateDot11HDFS(dev, buf);
5650                                break;
5651                        default:
5652                                zm_debug_msg1("Action Frame contain not support action field ", actionDetails);
5653                                break;
5654                }
5655                break;
5656        case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
5657            zfAggBlockAckActionFrame(dev, buf);
5658            break;
5659        case 17:        //Qos Management
5660                break;
5661    }
5662
5663    return 0;
5664}
5665
5666/* Determine the time not send beacon , if more than some value ,
5667   re-write the beacon start address */
5668void zfReWriteBeaconStartAddress(zdev_t* dev)
5669{
5670    zmw_get_wlan_dev(dev);
5671
5672    zmw_declare_for_critical_section();
5673
5674    zmw_enter_critical_section(dev);
5675    wd->tickIbssSendBeacon++;    // Increase 1 per 10ms .
5676    zmw_leave_critical_section(dev);
5677
5678    if ( wd->tickIbssSendBeacon == 40 )
5679    {
5680//        DbgPrint("20070727");
5681        zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow);
5682        zmw_enter_critical_section(dev);
5683        wd->tickIbssSendBeacon = 0;
5684        zmw_leave_critical_section(dev);
5685    }
5686}
5687
5688struct zsTkipSeed* zfStaGetRxSeed(zdev_t* dev, zbuf_t* buf)
5689{
5690    u8_t keyIndex;
5691    u8_t da0;
5692
5693    zmw_get_wlan_dev(dev);
5694
5695    /* if need not check MIC, return NULL */
5696    if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
5697         (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5698    {
5699        return NULL;
5700    }
5701
5702    da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5703
5704    if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80)
5705        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/
5706    else
5707        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/
5708    keyIndex = (keyIndex & 0xc0) >> 6;
5709
5710    return (&wd->sta.rxSeed[keyIndex]);
5711}
5712
5713void zfStaEnableSWEncryption(zdev_t *dev, u8_t value)
5714{
5715    zmw_get_wlan_dev(dev);
5716
5717    wd->sta.SWEncryptEnable = value;
5718    zfHpSWDecrypt(dev, 1);
5719    zfHpSWEncrypt(dev, 1);
5720}
5721
5722void zfStaDisableSWEncryption(zdev_t *dev)
5723{
5724    zmw_get_wlan_dev(dev);
5725
5726    wd->sta.SWEncryptEnable = 0;
5727    zfHpSWDecrypt(dev, 0);
5728    zfHpSWEncrypt(dev, 0);
5729}
5730
5731u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isHT40, u8_t signalStrength)
5732{
5733        u8_t  weightOfB           = 0;
5734        u8_t  weightOfAGBelowThr  = 0;
5735        u8_t  weightOfAGUpThr     = 15;
5736        u8_t  weightOfN20BelowThr = 15;
5737        u8_t  weightOfN20UpThr    = 30;
5738        u8_t  weightOfN40BelowThr = 16;
5739        u8_t  weightOfN40UpThr    = 32;
5740
5741    zmw_get_wlan_dev(dev);
5742
5743    if( isBMode == 0 )
5744        return (signalStrength + weightOfB);    // pure b mode , do not add the weight value for this AP !
5745    else
5746    {
5747        if( isHT == 0 && isHT40 == 0 )
5748        { // a , g , b/g mode ! add the weight value 15 for this AP if it's signal strength is more than some value !
5749            if( signalStrength < 18 ) // -77 dBm
5750                                return signalStrength + weightOfAGBelowThr;
5751                        else
5752                                return (signalStrength + weightOfAGUpThr);
5753        }
5754        else if( isHT == 1 && isHT40 == 0 )
5755        { // 80211n mode use 20MHz
5756            if( signalStrength < 23 ) // -72 dBm
5757                return (signalStrength + weightOfN20BelowThr);
5758            else
5759                return (signalStrength + weightOfN20UpThr);
5760        }
5761        else // isHT == 1 && isHT40 == 1
5762        { // 80211n mode use 40MHz
5763            if( signalStrength < 16 ) // -79 dBm
5764                return (signalStrength + weightOfN40BelowThr);
5765            else
5766                return (signalStrength + weightOfN40UpThr);
5767        }
5768    }
5769}
5770
5771u16_t zfStaAddIbssAdditionalIE(zdev_t* dev, zbuf_t* buf, u16_t offset)
5772{
5773        u16_t i;
5774
5775    zmw_get_wlan_dev(dev);
5776
5777    for (i=0; i<wd->sta.ibssAdditionalIESize; i++)
5778    {
5779        zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ibssAdditionalIE[i]);
5780    }
5781
5782    return offset;
5783}
5784