linux/drivers/staging/otus/80211core/cinit.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/*  Module Name : init.c                                                */
  18/*                                                                      */
  19/*  Abstract                                                            */
  20/*      This module contains init functions.                            */
  21/*                                                                      */
  22/*  NOTES                                                               */
  23/*      None                                                            */
  24/*                                                                      */
  25/************************************************************************/
  26#include "cprecomp.h"
  27#include "../hal/hpreg.h"
  28
  29extern const u8_t zcUpToAc[8];
  30
  31u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000,
  32                               24000, 12000, 6000, 54000, 36000, 18000, 9000};
  33u32_t zcIndextoRateN20L[16] = {6500, 13000, 19500, 26000, 39000, 52000, 58500,
  34                              65000, 13000, 26000, 39000, 52000, 78000, 104000,
  35                              117000, 130000};
  36u32_t zcIndextoRateN20S[16] = {7200, 14400, 21700, 28900, 43300, 57800, 65000,
  37                              72200, 14400, 28900, 43300, 57800, 86700, 115600,
  38                              130000, 144400};
  39u32_t zcIndextoRateN40L[16] = {13500, 27000, 40500, 54000, 81000, 108000, 121500,
  40                              135000, 27000, 54000, 81000, 108000, 162000, 216000,
  41                              243000, 270000};
  42u32_t zcIndextoRateN40S[16] = {15000, 30000, 45000, 60000, 90000, 120000, 135000,
  43                              150000, 30000, 60000, 90000, 120000, 180000, 240000,
  44                              270000, 300000};
  45
  46/************************************************************************/
  47/*                                                                      */
  48/*    FUNCTION DESCRIPTION                  zfTxGenWlanHeader           */
  49/*      Generate WLAN MAC header and LLC header.                        */
  50/*                                                                      */
  51/*    INPUTS                                                            */
  52/*      dev : device pointer                                            */
  53/*      buf : buffer pointer                                            */
  54/*      id : Index of TxD                                               */
  55/*      port : WLAN port                                                */
  56/*                                                                      */
  57/*    OUTPUTS                                                           */
  58/*      length of removed Ethernet header                               */
  59/*                                                                      */
  60/*    AUTHOR                                                            */
  61/*      Stephen             ZyDAS Technology Corporation    2005.5      */
  62/*                                                                      */
  63/************************************************************************/
  64u16_t zfTxGenWlanHeader(zdev_t* dev, zbuf_t* buf, u16_t* header, u16_t seq,
  65                        u8_t flag, u16_t plusLen, u16_t minusLen, u16_t port,
  66                        u16_t* da, u16_t* sa, u8_t up, u16_t *micLen,
  67                        u16_t* snap, u16_t snapLen, struct aggControl *aggControl)
  68{
  69
  70    u16_t len;
  71    u16_t macCtrl;
  72    u32_t phyCtrl;
  73    u16_t hlen = 16;
  74    u16_t icvLen = 0;
  75    u16_t wdsPortId;
  76    u16_t vap = 0;
  77    u16_t mcs = 0;
  78    u16_t mt = 0;
  79    u8_t  qosType;
  80    u8_t  b1, b2;
  81    u16_t wdsPort;
  82    u8_t  encExemptionActionType;
  83    u16_t rateProbingFlag = 0;
  84    u8_t  tkipFrameOffset = 0;
  85
  86#ifdef ZM_ENABLE_IBSS_WPA2PSK
  87    u8_t    res, peerIdx;
  88    u8_t    userIdx=0;
  89    u16_t   *iv16;
  90    u32_t   *iv32;
  91#endif
  92
  93    zmw_get_wlan_dev(dev);
  94
  95   /* Generate WLAN header */
  96    /* Frame control */
  97    header[4] = 0x0008 | (flag<<8);
  98    /* Duration */
  99    header[5] = 0x0000;
 100
 101    if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
 102    {
 103        /* ToDS bit */
 104        header[4] |= 0x0100;
 105
 106        /*Sometimes we wake up to tx/rx but AP still think we are sleeping, so still need to set this bit*/
 107        if ( zfPowerSavingMgrIsSleeping(dev) || wd->sta.psMgr.tempWakeUp == 1 )
 108        {
 109            header[4] |= 0x1000;
 110        }
 111
 112        /* Address 1 = BSSID */
 113        header[6] = wd->sta.bssid[0];
 114        header[7] = wd->sta.bssid[1];
 115        header[8] = wd->sta.bssid[2];
 116        /* Address 3 = DA */
 117        header[12] = da[0];
 118        header[13] = da[1];
 119        header[14] = da[2];
 120    }
 121    else if (wd->wlanMode == ZM_MODE_PSEUDO)
 122    {
 123        /* Address 1 = DA */
 124        header[6] = da[0];
 125        header[7] = da[1];
 126        header[8] = da[2];
 127        /* Address 3 = 00:00:00:00:00:00 */
 128        header[12] = 0;
 129        header[13] = 0;
 130        header[14] = 0;
 131
 132        /* PSEUDO test : WDS */
 133        if (wd->enableWDS)
 134        {
 135            /* ToDS and FromDS bit */
 136            header[4] |= 0x0300;
 137
 138            /* Address 4 = SA */
 139            header[16] = 0;
 140            header[17] = 0;
 141            header[18] = 0;
 142
 143            hlen = 19;
 144        }
 145    }
 146    else if (wd->wlanMode == ZM_MODE_IBSS)
 147    {
 148        /* Address 1 = DA */
 149        header[6] = da[0];
 150        header[7] = da[1];
 151        header[8] = da[2];
 152        /* Address 3 = BSSID */
 153        header[12] = wd->sta.bssid[0];
 154        header[13] = wd->sta.bssid[1];
 155        header[14] = wd->sta.bssid[2];
 156
 157#ifdef ZM_ENABLE_IBSS_WPA2PSK
 158        zmw_enter_critical_section(dev);
 159        res = zfStaFindOppositeByMACAddr(dev, da, &peerIdx);
 160        if(res == 0) // Find opposite in our OppositeInfo Structure !
 161        {
 162            userIdx = peerIdx;
 163        }
 164        zmw_leave_critical_section(dev);
 165#endif
 166    }
 167    else if (wd->wlanMode == ZM_MODE_AP)
 168    {
 169        if (port < 0x20)
 170        /* AP mode */
 171        {
 172            /* FromDS bit */
 173            header[4] |= 0x0200;
 174
 175            /* Address 1 = DA */
 176            header[6] = da[0];
 177            header[7] = da[1];
 178            header[8] = da[2];
 179            /* Address 3 = SA */
 180            header[12] = sa[0];
 181            header[13] = sa[1];
 182            header[14] = sa[2];
 183
 184            if (port < ZM_MAX_AP_SUPPORT)
 185            {
 186                vap = port;
 187                header[14] += (vap<<8);
 188            }
 189        }
 190        else
 191        /* WDS port */
 192        {
 193            /* ToDS and FromDS bit */
 194            header[4] |= 0x0300;
 195
 196            wdsPortId = port - 0x20;
 197
 198            /* Address 1 = RA */
 199            header[6] = wd->ap.wds.macAddr[wdsPortId][0];
 200            header[7] = wd->ap.wds.macAddr[wdsPortId][1];
 201            header[8] = wd->ap.wds.macAddr[wdsPortId][2];
 202            /* Address 3 = DA */
 203            header[12] = da[0];
 204            header[13] = da[1];
 205            header[14] = da[2];
 206            /* Address 4 = SA */
 207            header[16] = sa[0];
 208            header[17] = sa[1];
 209            header[18] = sa[2];
 210
 211            hlen = 19;
 212        }
 213    } /* else if (wd->wlanMode == ZM_MODE_AP) */
 214
 215    /* Address 2 = TA */
 216    header[9] = wd->macAddr[0];
 217    header[10] = wd->macAddr[1];
 218#ifdef ZM_VAPMODE_MULTILE_SSID
 219    header[11] = wd->macAddr[2]; //Multiple SSID
 220#else
 221    header[11] = wd->macAddr[2] + (vap<<8); //VAP
 222#endif
 223
 224    if ( (wd->wlanMode == ZM_MODE_IBSS) && (wd->XLinkMode) )
 225    {
 226        header[9]  = sa[0];
 227        header[10] = sa[1];
 228        header[11] = sa[2];
 229    }
 230
 231    /* Sequence Control */
 232    header[15] = seq;
 233
 234
 235    if (wd->wlanMode == ZM_MODE_AP)
 236    {
 237        zfApGetStaTxRateAndQosType(dev, da, &phyCtrl, &qosType, &rateProbingFlag);
 238        mt = (u16_t)(phyCtrl & 0x3);
 239        mcs = (u16_t)((phyCtrl >> 16) & 0x3f);
 240#if 1
 241        //zfApGetStaQosType(dev, da, &qosType);
 242
 243        /* if DA == WME STA */
 244        if (qosType == 1)
 245        {
 246            /* QoS data */
 247            header[4] |= 0x0080;
 248
 249            /* QoS Control */
 250            header[hlen] = up;
 251            hlen += 1;
 252        }
 253#endif
 254    }
 255
 256#if 0
 257    //AGG Test Code
 258    if (header[6] == 0x8000)
 259    {
 260        /* QoS data */
 261        header[4] |= 0x0080;
 262
 263        /* QoS Control */
 264        header[hlen] = 0;
 265        hlen += 1;
 266    }
 267#endif
 268
 269    if (wd->wlanMode == ZM_MODE_AP) {
 270        /* Todo: rate control here for qos field */
 271    }
 272    else {
 273        /* Rate control */
 274        zfStaGetTxRate(dev, da, &phyCtrl, &rateProbingFlag);
 275        mt = (u16_t)(phyCtrl & 0x3);
 276        mcs = (u16_t)((phyCtrl >> 16) & 0x3f);
 277    }
 278
 279    if (wd->txMCS != 0xff)
 280    {
 281        /* fixed rate */
 282            phyCtrl = ((u32_t)wd->txMCS<<16) + wd->txMT;
 283        mcs = wd->txMCS;
 284        mt = wd->txMT;
 285    }
 286
 287    if (wd->enableAggregation)
 288    {
 289        /* force enable aggregation */
 290        if (wd->enableAggregation==2 && !(header[6]&0x1))
 291        {
 292            /* QoS data */
 293            header[4] |= 0x0080;
 294
 295            /* QoS Control */
 296            header[hlen] = 0;
 297            hlen += 1;
 298        }
 299        /* if wd->enableAggregation=1 => force disable */
 300        /* if wd->enableAggregation=0 => auto */
 301    }
 302
 303#ifdef ZM_ENABLE_AGGREGATION
 304    /*
 305     * aggregation control
 306     */
 307
 308    /*
 309     * QoS data
 310     */
 311    if (wd->wlanMode == ZM_MODE_AP) {
 312        if (aggControl && mt == 2) {
 313            if (wd->enableAggregation==0 && !(header[6]&0x1))
 314            {
 315                header[4] |= 0x0080;
 316
 317                /*
 318                 * QoS Control
 319                 */
 320                header[hlen] = 0;
 321                hlen += 1;
 322            }
 323        }
 324    }
 325#endif
 326
 327    // MSDU Length
 328    len = zfwBufGetSize(dev, buf);
 329
 330    /* Generate control setting */
 331    /* Backoff, Non-Burst and hardware duration */
 332    macCtrl = 0x208;
 333
 334    /* ACK */
 335    if ((header[6] & 0x1) == 0x1)
 336    {
 337        /* multicast frame : Set NO-ACK bit */
 338        macCtrl |= 0x4;
 339    }
 340    else
 341    {
 342        /* unicast frame */
 343    #if 0
 344        // Enable RTS according to MPDU Lengths ( not MSDU Lengths )
 345        if (len >= wd->rtsThreshold)
 346        {
 347            /* Enable RTS */
 348            macCtrl |= 1;
 349        }
 350    #endif
 351    }
 352    /* VAP test code */
 353    //macCtrl |= 0x4;
 354
 355    if (wd->wlanMode == ZM_MODE_AP)
 356    {
 357        u8_t encryType;
 358        u16_t iv16;
 359        u32_t iv32;
 360
 361        /* Check whether this is a multicast frame */
 362        if ((header[6] & 0x1) == 0x1)
 363        {
 364            /* multicast frame */
 365            if (wd->ap.encryMode[vap] == ZM_TKIP)
 366            {
 367                wd->ap.iv16[vap]++;
 368
 369                if(wd->ap.iv16[vap] == 0)
 370                {
 371                    wd->ap.iv32[vap]++;
 372                }
 373
 374                b1 = (u8_t) (wd->ap.iv16[vap] >> 8);
 375                b2 = (b1 | 0x20) & 0x7f;
 376                header[hlen] = ((u16_t)b2 << 8) + b1;
 377                b1 = (u8_t) wd->ap.iv16[vap];
 378                b2 = 0x20 | (wd->ap.bcKeyIndex[vap] << 6);
 379                header[hlen+1] = ((u16_t)b2 << 8) + b1;
 380                header[hlen+2] = (u16_t) wd->ap.iv32[vap];
 381                header[hlen+3] = (u16_t) (wd->ap.iv32[vap] >> 16);
 382
 383                //macCtrl |= 0x80;
 384                macCtrl |= 0x40;
 385                icvLen = 4;
 386
 387                /* set hardware MIC */
 388                if ( (!(seq & 0xf))&&(!(flag & 0x4)) )
 389                {
 390                    macCtrl |= 0x100;
 391                    plusLen += 8;
 392                    *micLen = 8;
 393                }
 394
 395                header[4] |= 0x4000;
 396                hlen += 4;
 397            }
 398            else if (wd->ap.encryMode[vap] == ZM_AES)
 399            {
 400                wd->ap.iv16[vap]++;
 401
 402                if(wd->ap.iv16[vap] == 0)
 403                {
 404                    wd->ap.iv32[vap]++;
 405                }
 406
 407                b1 = (u8_t) wd->ap.iv16[vap];
 408                b2 = (u8_t) (wd->ap.iv16[vap] >> 8);
 409                header[hlen] = ((u16_t)b2 << 8) + b1;
 410                header[hlen+1] = 0x2000 | (wd->ap.bcKeyIndex[vap] << 14);
 411                header[hlen+2] = (u16_t) (wd->ap.iv32[vap]);
 412                header[hlen+3] = (u16_t) (wd->ap.iv32[vap] >> 16);
 413
 414                macCtrl |= 0xc0;
 415                icvLen = 8;  /* MIC */
 416
 417                header[4] |= 0x4000;
 418                hlen += 4;
 419            }
 420            #ifdef ZM_ENABLE_CENC
 421            else if (wd->ap.encryMode[vap] == ZM_CENC)
 422            {
 423                //u32_t txiv[4];
 424
 425                wd->ap.txiv[vap][0]++;
 426
 427                if (wd->ap.txiv[vap][0] == 0)
 428                {
 429                    wd->ap.txiv[vap][1]++;
 430                }
 431
 432                if (wd->ap.txiv[vap][1] == 0)
 433                {
 434                    wd->ap.txiv[vap][2]++;
 435                }
 436
 437                if (wd->ap.txiv[vap][2] == 0)
 438                {
 439                    wd->ap.txiv[vap][3]++;
 440                }
 441
 442                if (wd->ap.txiv[vap][3] == 0)
 443                {
 444                    wd->ap.txiv[vap][0] = 0;
 445                    wd->ap.txiv[vap][1] = 0;
 446                    wd->ap.txiv[vap][2] = 0;
 447                }
 448
 449                header[hlen] = (wd->ap.bcKeyIndex[vap] & 0x0001);    /* For Key Id and reserved field */
 450                header[hlen+1] = (u16_t)wd->ap.txiv[vap][0];
 451                header[hlen+2] = (u16_t)(wd->ap.txiv[vap][0] >> 16);
 452                header[hlen+3] = (u16_t)wd->ap.txiv[vap][1];
 453                header[hlen+4] = (u16_t)(wd->ap.txiv[vap][1] >> 16);
 454                header[hlen+5] = (u16_t)wd->ap.txiv[vap][2];
 455                header[hlen+6] = (u16_t)(wd->ap.txiv[vap][2] >> 16);
 456                header[hlen+7] = (u16_t)wd->ap.txiv[vap][3];
 457                header[hlen+8] = (u16_t)(wd->ap.txiv[vap][3] >> 16);
 458
 459                macCtrl |= 0x80;
 460                icvLen = 16;  /* MIC */
 461
 462                header[4] |= 0x4000;
 463                hlen += 9;
 464            }
 465            #endif //ZM_ENABLE_CENC
 466        }
 467        else
 468        {
 469            /* Get STA's encryption type */
 470            zfApGetStaEncryType(dev, da, &encryType);
 471
 472            if (encryType == ZM_TKIP)
 473            {
 474                /* Get iv16 and iv32 */
 475                zfApGetStaWpaIv(dev, da, &iv16, &iv32);
 476
 477                iv16++;
 478                if (iv16 == 0)
 479                {
 480                    iv32++;
 481                }
 482
 483                b1 = (u8_t) (iv16 >> 8);
 484                b2 = (b1 | 0x20) & 0x7f;
 485                header[hlen] = ((u16_t)b2 << 8) + b1;
 486                b1 = (u8_t) iv16;
 487                b2 = 0x20;
 488                header[hlen+1] = ((u16_t)b2 << 8) + b1;
 489                header[hlen+2] = (u16_t) iv32;
 490                header[hlen+3] = (u16_t) (iv32 >> 16);
 491
 492                //macCtrl |= 0x80;
 493                macCtrl |= 0x40;
 494                icvLen = 4;
 495
 496                /* set hardware MIC */
 497                if ( (!(seq & 0xf))&&(!(flag & 0x4)) )
 498                {
 499                    macCtrl |= 0x100;
 500                    plusLen += 8;
 501                    *micLen = 8;
 502                }
 503
 504                header[4] |= 0x4000;
 505                hlen += 4;
 506
 507                /* Set iv16 and iv32 */
 508                zfApSetStaWpaIv(dev, da, iv16, iv32);
 509            }
 510            else if (encryType == ZM_AES)
 511            {
 512                /* Get iv16 and iv32 */
 513                zfApGetStaWpaIv(dev, da, &iv16, &iv32);
 514
 515                iv16++;
 516                if (iv16 == 0)
 517                {
 518                    iv32++;
 519                }
 520
 521                b1 = (u8_t) iv16;
 522                b2 = (u8_t) (iv16 >> 8);
 523                header[hlen] = ((u16_t)b2 << 8) + b1;
 524                header[hlen+1] = 0x2000;
 525                header[hlen+2] = (u16_t) (iv32);
 526                header[hlen+3] = (u16_t) (iv32 >> 16);
 527
 528                macCtrl |= 0xc0;
 529                icvLen = 8;  /* MIC */
 530
 531                header[4] |= 0x4000;
 532                hlen += 4;
 533
 534                /* Set iv16 and iv32 */
 535                zfApSetStaWpaIv(dev, da, iv16, iv32);
 536            }
 537            #ifdef ZM_ENABLE_CENC
 538            else if (encryType == ZM_CENC)
 539            {
 540                u32_t txiv[4];
 541                u8_t keyIdx;
 542
 543                /* Get CENC TxIV */
 544                zfApGetStaCencIvAndKeyIdx(dev, da, txiv, &keyIdx);
 545
 546                txiv[0] += 2;
 547
 548                if (txiv[0] == 0 || txiv[0] == 1)
 549                {
 550                    txiv[1]++;
 551                }
 552
 553                if (txiv[1] == 0)
 554                {
 555                    txiv[2]++;
 556                }
 557
 558                if (txiv[2] == 0)
 559                {
 560                    txiv[3]++;
 561                }
 562
 563                if (txiv[3] == 0)
 564                {
 565                    txiv[0] = 0;
 566                    txiv[1] = 0;
 567                    txiv[2] = 0;
 568                }
 569
 570                header[hlen] = (keyIdx & 0x0001);    /* For Key Id and reserved field */
 571                header[hlen+1] = (u16_t)txiv[0];
 572                header[hlen+2] = (u16_t)(txiv[0] >> 16);
 573                header[hlen+3] = (u16_t)txiv[1];
 574                header[hlen+4] = (u16_t)(txiv[1] >> 16);
 575                header[hlen+5] = (u16_t)txiv[2];
 576                header[hlen+6] = (u16_t)(txiv[2] >> 16);
 577                header[hlen+7] = (u16_t)txiv[3];
 578                header[hlen+8] = (u16_t)(txiv[3] >> 16);
 579
 580                macCtrl |= 0x80;
 581                icvLen = 16;  /* MIC */
 582
 583                header[4] |= 0x4000;
 584                hlen += 9;
 585
 586                /* Set CENC IV */
 587                zfApSetStaCencIv(dev, da, txiv);
 588            }
 589            #endif //ZM_ENABLE_CENC
 590        }
 591
 592        /* protection mode */
 593        if (wd->ap.protectionMode == 1)
 594        {
 595            /* Enable Self-CTS */
 596            macCtrl &= 0xFFFC;
 597            macCtrl |= 2;
 598        }
 599
 600        /* Rate Control */
 601        if (port < 0x20)
 602        {
 603            /* AP */
 604            /* IV */
 605            if ((wd->ap.encryMode[vap] == ZM_WEP64) ||
 606                    (wd->ap.encryMode[vap] == ZM_WEP128) ||
 607                    (wd->ap.encryMode[vap] == ZM_WEP256))
 608            {
 609                header[4] |= 0x4000;
 610                header[hlen] = 0x0;   //IV
 611                header[hlen+1] = wd->ap.bcKeyIndex[vap] << 14; //IV with Keyid--CWYang(m)
 612                hlen += 2;
 613                icvLen = 4;
 614                macCtrl |= 0x40;
 615            }
 616        }
 617        else
 618        {
 619            /* WDS */
 620
 621            /* TODO : Fixed rate to 54M */
 622            phyCtrl = 0xc0001;   //PHY control L
 623
 624            /* WDS port checking */
 625            if ((wdsPort = (port - 0x20)) >= ZM_MAX_WDS_SUPPORT)
 626            {
 627                wdsPort = 0;
 628            }
 629
 630            #if 1
 631            /* IV */
 632            switch (wd->ap.wds.encryMode[wdsPort])
 633            {
 634            case ZM_WEP64:
 635            case ZM_WEP128:
 636            case ZM_WEP256:
 637                    header[4] |= 0x4000;
 638                    header[hlen] = 0x0;   //IV
 639                    header[hlen+1] = wd->ap.bcKeyIndex[vap] << 14; //IV with Keyid
 640                    hlen += 2;
 641                    icvLen = 4;
 642                    macCtrl |= 0x40;
 643                    break;
 644
 645            case ZM_TKIP:
 646                    wd->sta.iv16++;
 647
 648                    if ( wd->sta.iv16 == 0 )
 649                    {
 650                        wd->sta.iv32++;
 651                    }
 652
 653                    b1 = (u8_t) (wd->sta.iv16 >> 8);
 654                    b2 = (b1 | 0x20) & 0x7f;
 655                    header[hlen] = ((u16_t)b2 << 8) + b1;
 656                    b1 = (u8_t) wd->sta.iv16;
 657                    b2 = 0x20;
 658                    header[hlen+1] = ((u16_t)b2 << 8) + b1;
 659                    header[hlen+2] = (u16_t) wd->sta.iv32;
 660                    header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
 661
 662                    //macCtrl |= 0x80;
 663                    macCtrl |= 0x40;
 664                    icvLen = 4;
 665
 666                    /* set hardware MIC */
 667                    if ( (!(seq & 0xf))&&(!(flag & 0x4)) )
 668                    {
 669                        macCtrl |= 0x100;
 670                        plusLen += 8;
 671                        *micLen = 8;
 672                    }
 673
 674                    header[4] |= 0x4000;
 675                    hlen += 4;
 676                    break;
 677
 678            case ZM_AES:
 679                    wd->sta.iv16++;
 680                    if ( wd->sta.iv16 == 0 )
 681                    {
 682                        wd->sta.iv32++;
 683                    }
 684
 685                    b1 = (u8_t) wd->sta.iv16;
 686                    b2 = (u8_t) (wd->sta.iv16 >> 8);
 687                    header[hlen] = ((u16_t)b2 << 8) + b1;
 688                    header[hlen+1] = 0x2000;
 689                    header[hlen+2] = (u16_t) (wd->sta.iv32);
 690                    header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
 691
 692                    macCtrl |= 0xc0; /* Set to AES in control setting */
 693                    icvLen = 8;  /* MIC */
 694
 695                    header[4] |= 0x4000; /* Set WEP bit in wlan header */
 696                    hlen += 4; /* plus IV length */
 697                    break;
 698            }/* end of switch */
 699            #endif
 700        }
 701    }
 702    else   /* wd->wlanMode != ZM_MODE_AP */
 703    {
 704        encExemptionActionType = zfwGetPktEncExemptionActionType(dev, buf);
 705
 706        if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
 707        {
 708            #if 1
 709            /* if WME AP */
 710            if (wd->sta.wmeConnected != 0)
 711            {
 712                /* QoS data */
 713                header[4] |= 0x0080;
 714
 715                /* QoS Control */
 716                header[hlen] = up;
 717                hlen += 1;
 718            }
 719            #endif
 720
 721            if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION )
 722            {
 723                if ( wd->sta.authMode < ZM_AUTH_MODE_WPA )
 724                {   /* non-WPA */
 725                    if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED )
 726                    {
 727                        if ( (wd->sta.encryMode == ZM_WEP64)||
 728                             (wd->sta.encryMode == ZM_WEP128)||
 729                             (wd->sta.encryMode == ZM_WEP256) )
 730                        {
 731                            header[4] |= 0x4000;
 732                            header[hlen] = 0x0;   //IV
 733                            header[hlen+1] = 0x0; //IV
 734                            header[hlen+1] |= (((u16_t) wd->sta.keyId) << 14);
 735                            hlen += 2;
 736                            icvLen = 4;
 737
 738                            /* For Software WEP */
 739                            if ((wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) != 0)
 740                            {
 741                                u8_t keyLen = 5;
 742                                u8_t iv[3];
 743
 744                                iv[0] = 0x0;
 745                                iv[1] = 0x0;
 746                                iv[2] = 0x0;
 747
 748                                if (wd->sta.SWEncryMode[wd->sta.keyId] == ZM_WEP64)
 749                                {
 750                                    keyLen = 5;
 751                                }
 752                                else if (wd->sta.SWEncryMode[wd->sta.keyId] == ZM_WEP128)
 753                                {
 754                                    keyLen = 13;
 755                                }
 756                                else if (wd->sta.SWEncryMode[wd->sta.keyId] == ZM_WEP256)
 757                                {
 758                                    keyLen = 29;
 759                                }
 760
 761                                zfWEPEncrypt(dev, buf, (u8_t*) snap, snapLen, minusLen, keyLen,
 762                                        wd->sta.wepKey[wd->sta.keyId], iv);
 763                            }
 764                            else
 765                            {
 766                                macCtrl |= 0x40;
 767                            }
 768                        }
 769                    }
 770                }
 771                else
 772                {   /* WPA */
 773                    if ( wd->sta.wpaState >= ZM_STA_WPA_STATE_PK_OK )
 774                    {
 775                        wd->sta.iv16++;
 776                        if ( wd->sta.iv16 == 0 )
 777                        {
 778                            wd->sta.iv32++;
 779                        }
 780
 781                        /* set encryption mode */
 782                        if ( wd->sta.encryMode == ZM_TKIP )
 783                        {
 784                            b1 = (u8_t) (wd->sta.iv16 >> 8);
 785                            b2 = (b1 | 0x20) & 0x7f;
 786                            header[hlen] = ((u16_t)b2 << 8) + b1;
 787                            b1 = (u8_t) wd->sta.iv16;
 788                            b2 = 0x20;
 789
 790                            // header[hlen+1] = (((u16_t) wd->sta.keyId) << 14) | (((u16_t)b2 << 8) + b1);
 791                            // STA in infrastructure mode should use keyId = 0 to transmit unicast !
 792                            header[hlen+1] = (((u16_t)b2 << 8) + b1);
 793                            header[hlen+2] = (u16_t) wd->sta.iv32;
 794                            header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
 795
 796                            /* If software encryption enable */
 797                            if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0)
 798                            {
 799                                //macCtrl |= 0x80;
 800                                /* TKIP same to WEP */
 801                                macCtrl |= 0x40;
 802                                icvLen = 4;
 803
 804                                /* set hardware MIC */
 805                                if ( (!(seq & 0xf))&&(!(flag & 0x4)) )
 806                                {
 807                                    macCtrl |= 0x100;
 808                                    plusLen += 8;
 809                                    *micLen = 8;
 810                                }
 811                            }
 812                            else
 813                            {
 814                                u8_t mic[8];
 815                                u16_t offset;
 816                                u32_t icv;
 817                                u8_t RC4Key[16];
 818
 819                                /* TODO: Remove the criticial section here. */
 820                                zmw_declare_for_critical_section();
 821
 822                                zmw_enter_critical_section(dev);
 823                                /* Calculate MIC */
 824                                zfCalTxMic(dev, buf, (u8_t *)snap, snapLen, minusLen, da, sa, up, mic);
 825
 826                                offset = zfwBufGetSize(dev, buf);
 827
 828                                /* Append MIC to the buffer */
 829                                zfCopyToIntTxBuffer(dev, buf, mic, offset, 8);
 830                                zfwBufSetSize(dev, buf, offset+8);
 831                                zmw_leave_critical_section(dev);
 832
 833                                /* TKIP Key Mixing */
 834                                zfTkipPhase1KeyMix(wd->sta.iv32, &wd->sta.txSeed);
 835                                zfTkipPhase2KeyMix(wd->sta.iv16, &wd->sta.txSeed);
 836                                zfTkipGetseeds(wd->sta.iv16, RC4Key, &wd->sta.txSeed);
 837
 838                                /* Encrypt Data */
 839                                zfTKIPEncrypt(dev, buf, (u8_t *)snap, snapLen, minusLen, 16, RC4Key, &icv);
 840
 841                                icvLen = 4;
 842                                len += 8;
 843                            }
 844
 845                            header[4] |= 0x4000;
 846                            hlen += 4;
 847                        }
 848                        else if ( wd->sta.encryMode == ZM_AES )
 849                        {
 850                            b1 = (u8_t) wd->sta.iv16;
 851                            b2 = (u8_t) (wd->sta.iv16 >> 8);
 852                            header[hlen] = ((u16_t)b2 << 8) + b1;
 853                            // header[hlen+1] = (((u16_t) wd->sta.keyId) << 14) | (0x2000);
 854                            // STA in infrastructure mode should use keyId = 0 to transmit unicast !
 855                            header[hlen+1] = 0x2000;
 856                            header[hlen+2] = (u16_t) (wd->sta.iv32);
 857                            header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
 858
 859                            macCtrl |= 0xc0;
 860                            icvLen = 8;  /* MIC */
 861
 862                            header[4] |= 0x4000;
 863                            hlen += 4;
 864                        }
 865                        #ifdef ZM_ENABLE_CENC
 866                        else if ( wd->sta.encryMode == ZM_CENC )
 867                        {
 868                            /* Accumlate the PN sequence */
 869                            wd->sta.txiv[0] += 2;
 870
 871                            if (wd->sta.txiv[0] == 0 || wd->sta.txiv[0] == 1)
 872                            {
 873                                wd->sta.txiv[1]++;
 874                            }
 875
 876                            if (wd->sta.txiv[1] == 0)
 877                            {
 878                                wd->sta.txiv[2]++;
 879                            }
 880
 881                            if (wd->sta.txiv[2] == 0)
 882                            {
 883                                wd->sta.txiv[3]++;
 884                            }
 885
 886                            if (wd->sta.txiv[3] == 0)
 887                            {
 888                                wd->sta.txiv[0] = 0;
 889                                wd->sta.txiv[1] = 0;
 890                                wd->sta.txiv[2] = 0;
 891                            }
 892
 893                            header[hlen] = (wd->sta.cencKeyId & 0x0001);    /* For Key Id and reserved field */
 894                            header[hlen+1] = (u16_t) wd->sta.txiv[0];
 895                            header[hlen+2] = (u16_t) (wd->sta.txiv[0] >> 16);
 896                            header[hlen+3] = (u16_t) wd->sta.txiv[1];
 897                            header[hlen+4] = (u16_t) (wd->sta.txiv[1] >> 16);
 898                            header[hlen+5] = (u16_t) wd->sta.txiv[2];
 899                            header[hlen+6] = (u16_t) (wd->sta.txiv[2] >> 16);
 900                            header[hlen+7] = (u16_t) wd->sta.txiv[3];
 901                            header[hlen+8] = (u16_t) (wd->sta.txiv[3] >> 16);
 902
 903                            macCtrl |= 0x80;
 904                            icvLen = 16;  /* MIC */
 905
 906                            header[4] |= 0x4000;
 907                            hlen += 9;
 908                        }
 909                        #endif //ZM_ENABLE_CENC
 910                    }
 911                }
 912            } // if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION )
 913        } /* if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE ) */
 914
 915        if ( wd->wlanMode == ZM_MODE_IBSS )
 916        {
 917            if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION )
 918            {
 919#ifdef ZM_ENABLE_IBSS_WPA2PSK
 920                if( wd->sta.oppositeInfo[userIdx].wpaState >= ZM_STA_WPA_STATE_PK_OK || wd->sta.wpaState >= ZM_STA_WPA_STATE_PK_OK)
 921                {
 922                    int isUnicast = 1 ;
 923
 924                    if((da[0]& 0x1))
 925                    {
 926                        isUnicast = 0 ; // Not unicast , is broadcast
 927                    }
 928
 929                    if( wd->sta.ibssWpa2Psk == 1 )
 930                    { /* The IV order is not the same between unicast and broadcast ! */
 931                        if ( isUnicast )
 932                        {
 933                            iv16 = &wd->sta.oppositeInfo[userIdx].iv16;
 934                            iv32 = &wd->sta.oppositeInfo[userIdx].iv32;
 935                        }
 936                        else
 937                        {
 938                            iv16 = &wd->sta.iv16;
 939                            iv32 = &wd->sta.iv32;
 940                        }
 941                    }
 942                    else
 943                    {
 944                        iv16 = &wd->sta.iv16;
 945                        iv32 = &wd->sta.iv32;
 946                    }
 947
 948                    (*iv16)++;
 949                    if ( *iv16 == 0 )
 950                    {
 951                        *iv32++;
 952                    }
 953
 954                    if ( wd->sta.oppositeInfo[userIdx].encryMode == ZM_AES || wd->sta.encryMode == ZM_AES)
 955                    {
 956                        //printk("Station encryption mode is AES-CCMP\n") ;
 957                        b1 = (u8_t) (*iv16);
 958                        b2 = (u8_t) ((*iv16) >> 8);
 959                        header[hlen] = ((u16_t)b2 << 8) + b1;
 960
 961                        if ( isUnicast )
 962                        {
 963                            header[hlen+1] = 0x2000;
 964                        }
 965                        else
 966                        {
 967                            header[hlen+1] = 0x2000 | (((u16_t) wd->sta.keyId) << 14);
 968                        }
 969
 970                        header[hlen+2] = (u16_t) (*iv32);
 971                        header[hlen+3] = (u16_t) ((*iv32) >> 16);
 972                        macCtrl |= 0xc0;
 973                        icvLen = 8;  /* MIC */
 974                    }
 975
 976                    header[4] |= 0x4000;
 977                    hlen += 4;
 978                }
 979                else if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED)
 980                {
 981                    if ( (wd->sta.encryMode == ZM_WEP64)||
 982                        (wd->sta.encryMode == ZM_WEP128)||
 983                        (wd->sta.encryMode == ZM_WEP256) )
 984                    {
 985                        header[4] |= 0x4000;
 986                        header[hlen] = 0x0;   //IV
 987                        header[hlen+1] = 0x0; //IV
 988                        header[hlen+1] |= (((u16_t) wd->sta.keyId) << 14);
 989                        hlen += 2;
 990                        icvLen = 4;
 991                        macCtrl |= 0x40;
 992                    }
 993                }
 994#else
 995                /* ----- 20070405 add by Mxzeng ----- */
 996                if( wd->sta.wpaState >= ZM_STA_WPA_STATE_PK_OK )
 997                {
 998                    int isUnicast = 1 ;
 999
1000                    if((da[0]& 0x1))
1001                    {
1002                        isUnicast = 0 ; // Not unicast , is broadcast
1003                    }
1004
1005                    wd->sta.iv16++;
1006                    if ( wd->sta.iv16 == 0 )
1007                    {
1008                        wd->sta.iv32++;
1009                    }
1010
1011                    if ( wd->sta.encryMode == ZM_AES )
1012                    {
1013                        //printk("Station encryption mode is AES-CCMP\n") ;
1014                        b1 = (u8_t) wd->sta.iv16;
1015                        b2 = (u8_t) (wd->sta.iv16 >> 8);
1016                        header[hlen] = ((u16_t)b2 << 8) + b1;
1017
1018                        if ( isUnicast )
1019                        {
1020                            header[hlen+1] = 0x2000;
1021                        }
1022                        else
1023                        {
1024                            header[hlen+1] = 0x2000 | (((u16_t) wd->sta.keyId) << 14);
1025                        }
1026
1027                            header[hlen+2] = (u16_t) (wd->sta.iv32);
1028                            header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
1029                            macCtrl |= 0xc0;
1030                            icvLen = 8;  /* MIC */
1031                    }
1032
1033                    header[4] |= 0x4000;
1034                    hlen += 4;
1035                }
1036                else if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED)
1037                {
1038                    if ( (wd->sta.encryMode == ZM_WEP64)||
1039                         (wd->sta.encryMode == ZM_WEP128)||
1040                         (wd->sta.encryMode == ZM_WEP256) )
1041                    {
1042                        header[4] |= 0x4000;
1043                        header[hlen] = 0x0;   //IV
1044                        header[hlen+1] = 0x0; //IV
1045                        header[hlen+1] |= (((u16_t) wd->sta.keyId) << 14);
1046                        hlen += 2;
1047                        icvLen = 4;
1048                        macCtrl |= 0x40;
1049                    }
1050                }
1051#endif
1052            }   // End if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION )
1053        }   // End if ( wd->wlanMode == ZM_MODE_IBSS )
1054        else if ( wd->wlanMode == ZM_MODE_PSEUDO )
1055        {
1056            switch (wd->sta.encryMode)
1057                {
1058            case ZM_WEP64:
1059            case ZM_WEP128:
1060            case ZM_WEP256:
1061                header[4] |= 0x4000;
1062                header[hlen] = 0x0;   //IV
1063                header[hlen+1] = 0x0; //IV
1064                hlen += 2;
1065                icvLen = 4;
1066                macCtrl |= 0x40;
1067                break;
1068
1069            case ZM_TKIP:
1070            {
1071                wd->sta.iv16++;
1072                if ( wd->sta.iv16 == 0 )
1073                {
1074                    wd->sta.iv32++;
1075                }
1076
1077                b1 = (u8_t) (wd->sta.iv16 >> 8);
1078                b2 = (b1 | 0x20) & 0x7f;
1079                header[hlen] = ((u16_t)b2 << 8) + b1;
1080                b1 = (u8_t) wd->sta.iv16;
1081                b2 = 0x20;
1082                header[hlen+1] = ((u16_t)b2 << 8) + b1;
1083                header[hlen+2] = (u16_t) wd->sta.iv32;
1084                header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
1085
1086                //macCtrl |= 0x80;
1087                macCtrl |= 0x40;
1088                icvLen = 4;
1089
1090                /* set hardware MIC */
1091                if ( (!(seq & 0xf))&&(!(flag & 0x4)) )
1092                {
1093                    macCtrl |= 0x100;
1094                    plusLen += 8;
1095                    *micLen = 8;
1096                }
1097
1098                header[4] |= 0x4000;
1099                hlen += 4;
1100            }/* end of PSEUDO TKIP */
1101                break;
1102
1103            case ZM_AES:
1104            {
1105                wd->sta.iv16++;
1106                if ( wd->sta.iv16 == 0 )
1107                {
1108                    wd->sta.iv32++;
1109                }
1110
1111                b1 = (u8_t) wd->sta.iv16;
1112                b2 = (u8_t) (wd->sta.iv16 >> 8);
1113                header[hlen] = ((u16_t)b2 << 8) + b1;
1114                header[hlen+1] = 0x2000;
1115                header[hlen+2] = (u16_t) (wd->sta.iv32);
1116                header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16);
1117                macCtrl |= 0xc0;
1118                icvLen = 8;  /* MIC */
1119                header[4] |= 0x4000;
1120                hlen += 4;
1121            }/* end of PSEUDO AES */
1122                    break;
1123
1124              #ifdef ZM_ENABLE_CENC
1125              case ZM_CENC:
1126                    /* Accumlate the PN sequence */
1127                    wd->sta.txiv[0] += 2;
1128
1129                    if (wd->sta.txiv[0] == 0 || wd->sta.txiv[0] == 1)
1130                    {
1131                        wd->sta.txiv[1]++;
1132                    }
1133
1134                    if (wd->sta.txiv[1] == 0)
1135                    {
1136                        wd->sta.txiv[2]++;
1137                    }
1138
1139                    if (wd->sta.txiv[2] == 0)
1140                    {
1141                        wd->sta.txiv[3]++;
1142                    }
1143
1144                    if (wd->sta.txiv[3] == 0)
1145                    {
1146                        wd->sta.txiv[0] = 0;
1147                        wd->sta.txiv[1] = 0;
1148                        wd->sta.txiv[2] = 0;
1149                    }
1150
1151                    header[hlen] = 0;
1152                    header[hlen+1] = (u16_t) wd->sta.txiv[0];
1153                    header[hlen+2] = (u16_t) (wd->sta.txiv[0] >> 16);
1154                    header[hlen+3] = (u16_t) wd->sta.txiv[1];
1155                    header[hlen+4] = (u16_t) (wd->sta.txiv[1] >> 16);
1156                    header[hlen+5] = (u16_t) wd->sta.txiv[2];
1157                    header[hlen+6] = (u16_t) (wd->sta.txiv[2] >> 16);
1158                    header[hlen+7] = (u16_t) wd->sta.txiv[3];
1159                    header[hlen+8] = (u16_t) (wd->sta.txiv[3] >> 16);
1160
1161                    macCtrl |= 0x80;
1162                    icvLen = 16;  /* MIC */
1163
1164                    header[4] |= 0x4000;
1165                    hlen += 9;
1166                                break;
1167                    #endif //ZM_ENABLE_CENC
1168                        }/* end of switch */
1169                }
1170
1171        /* Generate control setting */
1172
1173        /* protection mode */
1174        if (wd->enableProtectionMode)
1175        {
1176            if (wd->enableProtectionMode==2)
1177            {
1178                /* Force enable protection: self cts  */
1179                macCtrl &= 0xFFFC;
1180                macCtrl |= 2;
1181            }
1182            /* if wd->enableProtectionMode=1 => force disable */
1183            /* if wd->enableProtectionMode=0 => auto */
1184        }
1185        else
1186        {
1187
1188            /* protection mode */
1189            if (wd->sta.bProtectionMode == TRUE)
1190            {
1191                /* Enable Self-CTS */
1192                macCtrl &= 0xFFFC;
1193                macCtrl |= 2;
1194            }
1195        }
1196
1197    }
1198
1199    if (wd->txMCS != 0xff)
1200    {
1201        /* fixed rate */
1202            phyCtrl = ((u32_t)wd->txMCS<<16) + wd->txMT;
1203        mcs = wd->txMCS;
1204        mt = wd->txMT;
1205    }
1206
1207    if (mt == 2)
1208    {
1209#if 0
1210        /* HT PT: 0 Mixed mode    1 Green field */
1211            if (wd->sta.preambleTypeHT == ZM_PREAMBLE_TYPE_GREEN_FIELD)
1212            {
1213            phyCtrl |= 0x4;     /* Bit 2 */
1214        }
1215#endif
1216        /* Bandwidth */
1217        if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ)
1218        {
1219            phyCtrl |= (0x80<<16);  /* BIT 23 */
1220        }
1221#if 0
1222        /* STBC */
1223        if (wd->sta.htCtrlSTBC<=0x3)
1224        {
1225            phyCtrl |= (wd->sta.htCtrlSTBC<<28);   /* BIT 23 */
1226        }
1227#endif
1228        /* Short GI */
1229        if(wd->sta.htCtrlSG)
1230        {
1231            phyCtrl |= (0x8000<<16);         /* BIT 31 */
1232        }
1233
1234        /* TA */
1235        if ( ((mcs >=0x8) && (mcs<=0xf))  || (wd->sta.htCtrlSTBC) )
1236        {
1237            phyCtrl |= 0x1800;               /* BIT 11 12 */
1238        }
1239    }
1240    else if(mt == 1)
1241    {
1242        #if 0
1243        //bug that cause OFDM rate become duplicate legacy rate
1244        /* Bandwidth */
1245        if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ)
1246        {
1247            phyCtrl |= (0x80<<16);  /* BIT 23 */
1248            mt = 3;                 /* duplicate legacy */
1249            phyCtrl |= mt;
1250        }
1251        #endif
1252    }
1253    else if(mt == 0)
1254    {
1255        /* CCK PT: Legcy Preamble: 1 long preamble    2 short preamble */
1256        if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_SHORT)
1257        {
1258               //phyCtrl |= 0x4;    /* BIT 2 */
1259        }
1260    }
1261
1262    /* TA */
1263    if (wd->sta.defaultTA)
1264    {
1265        phyCtrl |= 0x1000;
1266    }
1267    else
1268    {
1269        phyCtrl |= 0x0800;
1270    }
1271
1272    //Get CurrentTxRate -- CWYang(+)
1273    if ((mt == 0) || (mt == 1)) //B,G Rate
1274    {
1275        if (mcs < 16)
1276        {
1277            wd->CurrentTxRateKbps = zcIndextoRateBG[mcs];
1278        }
1279    }
1280    else if (mt == 2)
1281    {
1282        if (mcs < 16)
1283        {
1284            if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ)
1285            {
1286                if((phyCtrl & 0x80000000) != 0)
1287                {
1288                    /* Short GI 40 MHz MIMO Rate */
1289                    wd->CurrentTxRateKbps = zcIndextoRateN40S[mcs];
1290                }
1291                else
1292                {
1293                    /* Long GI 40 MHz MIMO Rate */
1294                    wd->CurrentTxRateKbps = zcIndextoRateN40L[mcs];
1295                }
1296            }
1297            else
1298            {
1299                if((phyCtrl & 0x80000000) != 0)
1300                {
1301                    /* Short GI 20 MHz MIMO Rate */
1302                    wd->CurrentTxRateKbps = zcIndextoRateN20S[mcs];
1303                }
1304                else
1305                {
1306                    /* Long GI 20 MHz MIMO Rate */
1307                    wd->CurrentTxRateKbps = zcIndextoRateN20L[mcs];
1308                }
1309            }
1310        }
1311    }
1312
1313    //802.11 header(include IV) = (hlen<<1)-8
1314    //ethernet frame = len
1315    //snap + mic = plusLen
1316    //ethernet header = minusLen
1317    //icv = icvLen
1318    //crc32 = 4
1319    //length=802.11 header+snap+(ethernet frame-ethernet header)+mic+icv+crc32
1320    header[0] = ((hlen<<1)-8)+plusLen+(len-minusLen)+icvLen+4;  //Length
1321
1322    // header[0] : MPDU Lengths
1323    if ((header[6] & 0x1) != 0x1) // Unicast Frame
1324    {
1325        if (header[0] >= wd->rtsThreshold)
1326        {
1327            /* Enable RTS */
1328            macCtrl |= 1;
1329        }
1330    }
1331
1332    if ( wd->sta.encryMode == ZM_TKIP )
1333        tkipFrameOffset = 8;
1334
1335    if( wd->sta.EnableHT != 1 )
1336    { // Aggregation should not be fragmented !
1337        if ( header[0] > ( wd->fragThreshold + tkipFrameOffset ) )
1338        {
1339            return 0; // Need to be fragmented ! !
1340        }
1341    }
1342
1343    //if ( wd->sta.encryMode == ZM_TKIP )
1344    //{
1345    //    zm_debug_msg1("ctrl length = ", header[0]);
1346    //}
1347
1348    //MAC control
1349    if (rateProbingFlag != 0)
1350    {
1351        macCtrl |= 0x8000;
1352    }
1353    header[1] = macCtrl;
1354    //PHY control L
1355    header[2] = (u16_t) ((phyCtrl&0xffff) | 0x700 | (zcUpToAc[up&0x7]<<13));
1356    //PHY control H
1357    header[3] = (u16_t) ((phyCtrl>>16) | 0x700);
1358
1359    if (wd->enableAggregation)
1360    {
1361        /* force enable aggregation */
1362        if (wd->enableAggregation==2 && !(header[6]&0x1))
1363        {
1364            if (((header[2] & 0x3) == 2))
1365            {
1366                /* Enable aggregation */
1367                header[1] |= 0x20;
1368            }
1369        }
1370        /* if wd->enableAggregation=1 => force disable */
1371        /* if wd->enableAggregation=0 => auto */
1372    }
1373
1374#ifdef ZM_ENABLE_AGGREGATION
1375    if (wd->addbaComplete) {
1376        #ifdef ZM_BYPASS_AGGR_SCHEDULING
1377        if (!(header[6]&0x1) && !rateProbingFlag && (wd->enableAggregation != 1))
1378        {
1379            if (((header[2] & 0x3) == 2))
1380            {
1381                /* Unicast frame with HT rate => Enable aggregation */
1382                /* We only support software encryption in single packet mode */
1383                if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 &&
1384                    (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0)
1385                {
1386                    /* Set aggregation group bits per AC */
1387                    header[1] |= (0x20 | (zcUpToAc[up&0x7]<<10));
1388
1389                    //if (wd->sta.currentFrequency < 3000)
1390                    {
1391                        /* issue: -PB42 Enable RTS/CTS to prevent OWL Tx hang up */
1392                        /* If this is Owl Ap, enable RTS/CTS protect */
1393                        if ( (wd->sta.athOwlAp == 1) || (wd->sta.RTSInAGGMode == TRUE) )
1394                        {
1395                            header[1] &= 0xfffc;
1396                            header[1] |= 0x1;
1397                        }
1398
1399                        /* Enable RIFS : workaround 854T RTS/CTS */
1400                        /* Bit13 : TI enable RIFS */
1401                        //header[1] |= 0x2000;
1402                    }
1403                }
1404            }
1405        }
1406        #else
1407        /*
1408         * aggregation ampduIndication control
1409         */
1410        if (aggControl && aggControl->aggEnabled) {
1411            if (wd->enableAggregation==0 && !(header[6]&0x1))
1412            {
1413                if (((header[2] & 0x3) == 2))
1414                {
1415                    /* Enable aggregation */
1416                    header[1] |= 0x20;
1417                    if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication)
1418                        header[1] |= 0x4000;
1419                }
1420                else {
1421                    zm_debug_msg1("no aggr, header[2]&0x3 = ",header[2] & 0x3)
1422                    aggControl->aggEnabled = 0;
1423                }
1424            }
1425            else {
1426                zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
1427                zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(header[6]&0x1));
1428                aggControl->aggEnabled = 0;
1429            }
1430        }
1431        #endif
1432
1433        #ifdef ZM_AGGR_BIT_ON
1434        if (!(header[6]&0x1) && !rateProbingFlag)
1435        {
1436            if (((header[2] & 0x3) == 2))
1437            {
1438                /* Unicast frame with HT rate => Enable aggregation */
1439                /* Set aggregation group bits per AC */
1440                header[1] |= (0x20 | (zcUpToAc[up&0x7]<<10));
1441
1442                //if (wd->sta.currentFrequency < 3000)
1443                {
1444                    /* Enable RTS/CTS to prevent OWL Tx hang up */
1445                    header[1] &= 0xfffc;
1446                    header[1] |= 0x1;
1447                }
1448            }
1449        }
1450        #endif
1451    }
1452#endif
1453
1454    return (hlen<<1);
1455}
1456
1457
1458u16_t zfTxGenMmHeader(zdev_t* dev, u8_t frameType, u16_t* dst,
1459        u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
1460{
1461    //u16_t bodyLen;
1462    u8_t  hlen = 32;        // MAC ctrl + PHY ctrl + 802.11 MM header
1463
1464    zmw_get_wlan_dev(dev);
1465
1466    zmw_declare_for_critical_section();
1467
1468    /* Generate control setting */
1469    //bodyLen = zfwBufGetSize(dev, buf);
1470    header[0] = 24+len+4;   //Length
1471    if ((dst[0] & 0x1) != 0) //Broadcast, multicast frames
1472    {
1473        header[1] = 0xc;            //MAC control, backoff + noack
1474    }
1475    else
1476    {
1477        header[1] = 0x8;            //MAC control, backoff + (ack)
1478    }
1479    /* Dualband Management frame tx Rate */
1480    if (wd->wlanMode == ZM_MODE_AP)
1481    {
1482        if (wd->frequency < 3000)
1483        {
1484            /* CCK 1M */
1485            header[2] = 0x0f00;          //PHY control L
1486            header[3] = 0x0000;          //PHY control H
1487        }
1488        else
1489        {
1490            /* CCK 6M */
1491            header[2] = 0x0f01;          //PHY control L
1492            header[3] = 0x000B;          //PHY control H
1493        }
1494    }
1495    else
1496    {
1497        if (wd->sta.currentFrequency < 3000)
1498        {
1499            /* CCK 2M */
1500            header[2] = 0x0f00;          //PHY control L
1501            header[3] = 0x0001;          //PHY control H
1502        }
1503        else
1504        {
1505            /* CCK 6M */
1506            header[2] = 0x0f01;          //PHY control L
1507            header[3] = 0x000B;          //PHY control H
1508        }
1509    }
1510    /* Generate WLAN header */
1511    /* Frame control */
1512    header[4+0] = frameType;
1513    /* Duration */
1514    header[4+1] = 0;
1515
1516    if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
1517    {
1518        if ( frameType == ZM_WLAN_FRAME_TYPE_PROBEREQ )
1519        {
1520            header[4+8] = 0xFFFF;
1521            header[4+9] = 0xFFFF;
1522            header[4+10] = 0xFFFF;
1523        }
1524        else if ( frameType == ZM_WLAN_FRAME_TYPE_BA ) {
1525            /* do nothing */
1526        }
1527        else
1528        {
1529            header[4+8] = wd->sta.bssid[0];
1530            header[4+9] = wd->sta.bssid[1];
1531            header[4+10] = wd->sta.bssid[2];
1532        }
1533    }
1534    else if (wd->wlanMode == ZM_MODE_PSEUDO)
1535    {
1536        /* Address 3 = 00:00:00:00:00:00 */
1537        header[4+8] = 0;
1538        header[4+9] = 0;
1539        header[4+10] = 0;
1540    }
1541    else if (wd->wlanMode == ZM_MODE_IBSS)
1542    {
1543        header[4+8] = wd->sta.bssid[0];
1544        header[4+9] = wd->sta.bssid[1];
1545        header[4+10] = wd->sta.bssid[2];
1546
1547        if ( frameType == ZM_WLAN_FRAME_TYPE_ATIM )
1548        {
1549            /* put ATIM to queue 5th */
1550            //header[2] |= (ZM_BIT_13|ZM_BIT_14);
1551            header[2] |= ZM_BIT_15;
1552        }
1553    }
1554    else if (wd->wlanMode == ZM_MODE_AP)
1555    {
1556        /* Address 3 = BSSID */
1557        header[4+8] = wd->macAddr[0];
1558        header[4+9] = wd->macAddr[1];
1559#ifdef ZM_VAPMODE_MULTILE_SSID
1560        header[4+10] = wd->macAddr[2]; //Multiple SSID
1561#else
1562        header[4+10] = wd->macAddr[2] + (vap<<8); //VAP
1563#endif
1564        //if in scan, must set address 3 to broadcast because of some ap would care this
1565        //if ((wd->heartBeatNotification & ZM_BSSID_LIST_SCAN)
1566        //        == ZM_BSSID_LIST_SCAN)
1567        //if FrameType is Probe Request, Address3 should be boradcast
1568        if (frameType == ZM_WLAN_FRAME_TYPE_PROBEREQ)
1569        {
1570            header[4+8] = 0xFFFF;
1571            header[4+9] = 0xFFFF;
1572            header[4+10] = 0xFFFF;
1573        }
1574    }
1575
1576    /* Address 1 = DA */
1577    header[4+2] = dst[0];
1578    header[4+3] = dst[1];
1579    header[4+4] = dst[2];
1580
1581    /* Address 2 = SA */
1582    header[4+5] = wd->macAddr[0];
1583    header[4+6] = wd->macAddr[1];
1584    if (wd->wlanMode == ZM_MODE_AP)
1585    {
1586#ifdef ZM_VAPMODE_MULTILE_SSID
1587        header[4+7] = wd->macAddr[2]; //Multiple SSID
1588#else
1589        header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
1590#endif
1591    }
1592    else
1593    {
1594        header[4+7] = wd->macAddr[2];
1595    }
1596
1597    /* Sequence Control */
1598    zmw_enter_critical_section(dev);
1599    header[4+11] = ((wd->mmseq++)<<4);
1600    zmw_leave_critical_section(dev);
1601
1602    if( frameType == ZM_WLAN_FRAME_TYPE_QOS_NULL )
1603    {
1604        /*Qos Control*/
1605        header[4+12] = 0x0;
1606        hlen+=2;
1607        header[0]+=2;
1608    }
1609
1610    if ( encrypt )
1611    {
1612        if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED )
1613        {
1614            if ( (wd->sta.encryMode == ZM_WEP64)||
1615                 (wd->sta.encryMode == ZM_WEP128)||
1616                 (wd->sta.encryMode == ZM_WEP256) )
1617            {
1618                header[4] |= 0x4000;
1619                header[16] = 0x0;   //IV
1620                header[17] = 0x0; //IV
1621                header[17] |= (((u16_t) wd->sta.keyId) << 14);
1622                hlen += 4;
1623
1624                header[0] += 8;         // icvLen = 4;
1625                header[1] |= 0x40;      // enable encryption on macCtrl
1626             }
1627        }
1628    }
1629
1630    // Enable HW duration
1631    if ( frameType != ZM_WLAN_FRAME_TYPE_PSPOLL )
1632    {
1633        header[1] |= 0x200;
1634    }
1635
1636    return hlen;
1637}
1638
1639void zfInitMacApMode(zdev_t* dev)
1640{
1641    u16_t i;
1642
1643    zmw_get_wlan_dev(dev);
1644
1645    zfHpEnableBeacon(dev, ZM_MODE_AP, (wd->beaconInterval/wd->ap.vapNumber), 1, 0);
1646
1647    /* AP mode */
1648    zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_AP);
1649
1650    /* VAP test code */
1651    /* AP + VAP mode */
1652    if (wd->ap.vapNumber >= 2)
1653    {
1654        for (i=1; i<ZM_MAX_AP_SUPPORT; i++)
1655        {
1656            if (((wd->ap.apBitmap >> i) & 0x1) != 0)
1657            {
1658                u16_t mac[3];
1659                mac[0] = wd->macAddr[0];
1660                mac[1] = wd->macAddr[1];
1661#ifdef ZM_VAPMODE_MULTILE_SSID
1662                mac[2] = wd->macAddr[2]; //Multiple SSID
1663#else
1664                mac[2] = wd->macAddr[2] + (i<<8); //VAP
1665#endif
1666                zfHpSetMacAddress(dev, mac, i);
1667
1668            }
1669        }
1670    }
1671
1672    /* basic rate setting */
1673    zfHpSetBasicRateSet(dev, wd->bRateBasic, wd->gRateBasic);
1674
1675    /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME AP default. */
1676    zfUpdateDefaultQosParameter(dev, 1);
1677
1678    return;
1679}
1680
1681u16_t zfChGetNextChannel(zdev_t* dev, u16_t frequency, u8_t* pbPassive)
1682{
1683    u8_t   i;
1684    u8_t   bPassive;
1685
1686    zmw_get_wlan_dev(dev);
1687
1688    /* Avoid NULL value */
1689    if ( pbPassive == NULL )
1690    {
1691        pbPassive = &bPassive;
1692    }
1693
1694    for( i=0; i<wd->regulationTable.allowChannelCnt; i++ )
1695    {
1696        if ( wd->regulationTable.allowChannel[i].channel == frequency )
1697        {
1698            if ( i == (wd->regulationTable.allowChannelCnt-1) )
1699            {
1700                i = 0;
1701            }
1702            else
1703            {
1704                i++;
1705            }
1706
1707            if ( wd->regulationTable.allowChannel[i].channelFlags
1708                    & ZM_REG_FLAG_CHANNEL_PASSIVE )
1709            {
1710                *pbPassive = TRUE;
1711            }
1712            else
1713            {
1714                *pbPassive = FALSE;
1715            }
1716
1717            return wd->regulationTable.allowChannel[i].channel;
1718        }
1719    }
1720
1721    return 0xffff;
1722}
1723
1724u16_t zfChGetFirstChannel(zdev_t* dev, u8_t* pbPassive)
1725{
1726    u8_t   bPassive;
1727
1728    zmw_get_wlan_dev(dev);
1729
1730    /* Avoid NULL value */
1731    if ( pbPassive == NULL )
1732    {
1733        pbPassive = &bPassive;
1734    }
1735
1736   if ( wd->regulationTable.allowChannel[0].channelFlags & ZM_REG_FLAG_CHANNEL_PASSIVE )
1737    {
1738        *pbPassive = TRUE;
1739    }
1740    else
1741    {
1742        *pbPassive = FALSE;
1743    }
1744
1745    return wd->regulationTable.allowChannel[0].channel;
1746}
1747
1748u16_t zfChGetFirst2GhzChannel(zdev_t* dev)
1749{
1750    u8_t    i;
1751
1752    zmw_get_wlan_dev(dev);
1753
1754    for( i=0; i<wd->regulationTable.allowChannelCnt; i++ )
1755    {
1756        if ( wd->regulationTable.allowChannel[i].channel < 3000 )
1757        {
1758            /* find the first 2Ghz channel */
1759            return wd->regulationTable.allowChannel[i].channel;
1760        }
1761    }
1762
1763    /* Can not find any 2Ghz channel */
1764    return 0;
1765}
1766
1767u16_t zfChGetFirst5GhzChannel(zdev_t* dev)
1768{
1769    u8_t    i;
1770
1771    zmw_get_wlan_dev(dev);
1772
1773    for( i=0; i<wd->regulationTable.allowChannelCnt; i++ )
1774    {
1775        if ( wd->regulationTable.allowChannel[i].channel > 3000 )
1776        {
1777            /* find the first 5Ghz channel */
1778            return wd->regulationTable.allowChannel[i].channel;
1779        }
1780    }
1781
1782    /* Can not find any 5Ghz channel */
1783    return 0;
1784}
1785
1786u16_t zfChGetLastChannel(zdev_t* dev, u8_t* pbPassive)
1787{
1788    u8_t   bPassive;
1789    u8_t   ChannelIndex;
1790
1791    zmw_get_wlan_dev(dev);
1792
1793    ChannelIndex = wd->regulationTable.allowChannelCnt-1;
1794
1795    /* Avoid NULL value */
1796    if ( pbPassive == NULL )
1797    {
1798        pbPassive = &bPassive;
1799    }
1800
1801    if ( wd->regulationTable.allowChannel[ChannelIndex].channelFlags
1802            & ZM_REG_FLAG_CHANNEL_PASSIVE )
1803    {
1804        *pbPassive = TRUE;
1805    }
1806    else
1807    {
1808        *pbPassive = FALSE;
1809    }
1810
1811    return wd->regulationTable.allowChannel[ChannelIndex].channel;
1812}
1813
1814u16_t zfChGetLast5GhzChannel(zdev_t* dev)
1815{
1816    u8_t    i;
1817    u16_t   last5Ghzfrequency;
1818
1819    zmw_get_wlan_dev(dev);
1820
1821    last5Ghzfrequency = 0;
1822    for( i=0; i<wd->regulationTable.allowChannelCnt; i++ )
1823    {
1824        if ( wd->regulationTable.allowChannel[i].channel > 3000 )
1825        {
1826            last5Ghzfrequency = wd->regulationTable.allowChannel[i].channel;
1827        }
1828    }
1829
1830    return last5Ghzfrequency;
1831}
1832
1833/* freqBand = 0 => auto check   */
1834/*          = 1 => 2.4 GHz band */
1835/*          = 2 => 5 GHz band   */
1836u16_t zfChNumToFreq(zdev_t* dev, u8_t ch, u8_t freqBand)
1837{
1838    u16_t freq = 0xffff;
1839
1840    if ( freqBand == 0 )
1841    {
1842        if (ch > 14)
1843        {   /* adapter is at 5 GHz band */
1844            freqBand = 2;
1845        }
1846        else
1847        {
1848            freqBand = 1;
1849        }
1850    }
1851
1852    if ( freqBand == 2 )
1853    {   /* the channel belongs to 5 GHz band */
1854        if ( (ch >= 184)&&(ch <= 196) )
1855        {
1856            freq = 4000 + ch*5;
1857        }
1858        else
1859        {
1860            freq = 5000 + ch*5;
1861        }
1862    }
1863    else
1864    {   /* the channel belongs to 2.4 GHz band */
1865        if ( ch == 14 )
1866        {
1867            freq = ZM_CH_G_14;
1868        }
1869        else
1870        {
1871            freq = ZM_CH_G_1 + (ch-1)*5;
1872        }
1873    }
1874
1875    return freq;
1876}
1877
1878u8_t zfChFreqToNum(u16_t freq, u8_t* pbIs5GBand)
1879{
1880    u8_t   ch;
1881    u8_t   Is5GBand;
1882
1883    /* to avoid NULL value */
1884    if ( pbIs5GBand == NULL )
1885    {
1886        pbIs5GBand = &Is5GBand;
1887    }
1888
1889    *pbIs5GBand = FALSE;
1890
1891    if ( freq == ZM_CH_G_14 )
1892    {
1893        ch = 14;
1894    }
1895    else if ( freq < 4000 )
1896    {
1897        ch = (freq - ZM_CH_G_1) / 5 + 1;
1898    }
1899    else if ( freq < 5000 )
1900    {
1901        ch = (freq - 4000) / 5;
1902        *pbIs5GBand = TRUE;
1903    }
1904    else
1905    {
1906        ch = (freq - 5000) / 5;
1907        *pbIs5GBand = TRUE;
1908    }
1909
1910    return ch;
1911}
1912