linux/drivers/staging/rt2860/common/cmm_asic.c
<<
>>
Prefs
   1/*
   2 *************************************************************************
   3 * Ralink Tech Inc.
   4 * 5F., No.36, Taiyuan St., Jhubei City,
   5 * Hsinchu County 302,
   6 * Taiwan, R.O.C.
   7 *
   8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify  *
  11 * it under the terms of the GNU General Public License as published by  *
  12 * the Free Software Foundation; either version 2 of the License, or     *
  13 * (at your option) any later version.                                   *
  14 *                                                                       *
  15 * This program is distributed in the hope that it will be useful,       *
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  18 * GNU General Public License for more details.                          *
  19 *                                                                       *
  20 * You should have received a copy of the GNU General Public License     *
  21 * along with this program; if not, write to the                         *
  22 * Free Software Foundation, Inc.,                                       *
  23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  24 *                                                                       *
  25 *************************************************************************
  26
  27        Module Name:
  28        cmm_asic.c
  29
  30        Abstract:
  31        Functions used to communicate with ASIC
  32
  33        Revision History:
  34        Who                     When                    What
  35        --------        ----------              ----------------------------------------------
  36*/
  37
  38#include "../rt_config.h"
  39
  40/* Reset the RFIC setting to new series */
  41struct rt_rtmp_rf_regs RF2850RegTable[] = {
  42/*              ch       R1              R2              R3(TX0~4=0) R4 */
  43        {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}
  44        ,
  45        {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}
  46        ,
  47        {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}
  48        ,
  49        {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}
  50        ,
  51        {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}
  52        ,
  53        {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}
  54        ,
  55        {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}
  56        ,
  57        {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}
  58        ,
  59        {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}
  60        ,
  61        {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}
  62        ,
  63        {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}
  64        ,
  65        {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}
  66        ,
  67        {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}
  68        ,
  69        {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}
  70        ,
  71
  72        /* 802.11 UNI / HyperLan 2 */
  73        {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}
  74        ,
  75        {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}
  76        ,
  77        {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}
  78        ,
  79        {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}
  80        ,
  81        {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}
  82        ,
  83        {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}
  84        ,
  85        {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}
  86        ,
  87        {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}
  88        ,
  89        {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}
  90        ,
  91        {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}
  92        ,
  93        {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}
  94        ,
  95        {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}
  96        ,                       /* Plugfest#4, Day4, change RFR3 left4th 9->5. */
  97
  98        /* 802.11 HyperLan 2 */
  99        {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}
 100        ,
 101
 102        /* 2008.04.30 modified */
 103        /* The system team has AN to improve the EVM value */
 104        /* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */
 105        {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}
 106        ,
 107        {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}
 108        ,
 109        {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}
 110        ,
 111
 112        {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}
 113        ,
 114        {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}
 115        ,
 116        {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}
 117        ,
 118        {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}
 119        ,
 120        {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}
 121        ,
 122        {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}
 123        ,
 124        {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}
 125        ,                       /* 0x980ed1bb->0x980ed15b required by Rory 20070927 */
 126        {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}
 127        ,
 128        {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}
 129        ,
 130        {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}
 131        ,
 132        {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}
 133        ,
 134        {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}
 135        ,
 136
 137        /* 802.11 UNII */
 138        {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}
 139        ,
 140        {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}
 141        ,
 142        {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}
 143        ,
 144        {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}
 145        ,
 146        {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}
 147        ,
 148        {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}
 149        ,
 150        {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}
 151        ,
 152        {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}
 153        ,
 154        {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}
 155        ,
 156        {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}
 157        ,
 158        {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}
 159        ,
 160
 161        /* Japan */
 162        {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}
 163        ,
 164        {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}
 165        ,
 166        {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}
 167        ,
 168        {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}
 169        ,
 170        {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}
 171        ,
 172        {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}
 173        ,
 174        {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}
 175        ,
 176
 177        /* still lack of MMAC(Japan) ch 34,38,42,46 */
 178};
 179
 180u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs));
 181
 182struct rt_frequency_item FreqItems3020[] = {
 183        /**************************************************/
 184        /* ISM : 2.4 to 2.483 GHz                         // */
 185        /**************************************************/
 186        /* 11g */
 187        /**************************************************/
 188        /*-CH---N-------R---K----------- */
 189        {1, 241, 2, 2}
 190        ,
 191        {2, 241, 2, 7}
 192        ,
 193        {3, 242, 2, 2}
 194        ,
 195        {4, 242, 2, 7}
 196        ,
 197        {5, 243, 2, 2}
 198        ,
 199        {6, 243, 2, 7}
 200        ,
 201        {7, 244, 2, 2}
 202        ,
 203        {8, 244, 2, 7}
 204        ,
 205        {9, 245, 2, 2}
 206        ,
 207        {10, 245, 2, 7}
 208        ,
 209        {11, 246, 2, 2}
 210        ,
 211        {12, 246, 2, 7}
 212        ,
 213        {13, 247, 2, 2}
 214        ,
 215        {14, 248, 2, 4}
 216        ,
 217};
 218
 219u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item));
 220
 221void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable)
 222{
 223        u8 i;
 224        HT_FBK_CFG0_STRUC HtCfg0;
 225        HT_FBK_CFG1_STRUC HtCfg1;
 226        LG_FBK_CFG0_STRUC LgCfg0;
 227        LG_FBK_CFG1_STRUC LgCfg1;
 228        struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate;
 229
 230        /* set to initial value */
 231        HtCfg0.word = 0x65432100;
 232        HtCfg1.word = 0xedcba988;
 233        LgCfg0.word = 0xedcba988;
 234        LgCfg1.word = 0x00002100;
 235
 236        pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1;
 237        for (i = 1; i < *((u8 *)pRateTable); i++) {
 238                pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i;
 239                switch (pCurrTxRate->Mode) {
 240                case 0: /*CCK */
 241                        break;
 242                case 1: /*OFDM */
 243                        {
 244                                switch (pCurrTxRate->CurrMCS) {
 245                                case 0:
 246                                        LgCfg0.field.OFDMMCS0FBK =
 247                                            (pNextTxRate->Mode ==
 248                                             MODE_OFDM) ? (pNextTxRate->
 249                                                           CurrMCS +
 250                                                           8) : pNextTxRate->
 251                                            CurrMCS;
 252                                        break;
 253                                case 1:
 254                                        LgCfg0.field.OFDMMCS1FBK =
 255                                            (pNextTxRate->Mode ==
 256                                             MODE_OFDM) ? (pNextTxRate->
 257                                                           CurrMCS +
 258                                                           8) : pNextTxRate->
 259                                            CurrMCS;
 260                                        break;
 261                                case 2:
 262                                        LgCfg0.field.OFDMMCS2FBK =
 263                                            (pNextTxRate->Mode ==
 264                                             MODE_OFDM) ? (pNextTxRate->
 265                                                           CurrMCS +
 266                                                           8) : pNextTxRate->
 267                                            CurrMCS;
 268                                        break;
 269                                case 3:
 270                                        LgCfg0.field.OFDMMCS3FBK =
 271                                            (pNextTxRate->Mode ==
 272                                             MODE_OFDM) ? (pNextTxRate->
 273                                                           CurrMCS +
 274                                                           8) : pNextTxRate->
 275                                            CurrMCS;
 276                                        break;
 277                                case 4:
 278                                        LgCfg0.field.OFDMMCS4FBK =
 279                                            (pNextTxRate->Mode ==
 280                                             MODE_OFDM) ? (pNextTxRate->
 281                                                           CurrMCS +
 282                                                           8) : pNextTxRate->
 283                                            CurrMCS;
 284                                        break;
 285                                case 5:
 286                                        LgCfg0.field.OFDMMCS5FBK =
 287                                            (pNextTxRate->Mode ==
 288                                             MODE_OFDM) ? (pNextTxRate->
 289                                                           CurrMCS +
 290                                                           8) : pNextTxRate->
 291                                            CurrMCS;
 292                                        break;
 293                                case 6:
 294                                        LgCfg0.field.OFDMMCS6FBK =
 295                                            (pNextTxRate->Mode ==
 296                                             MODE_OFDM) ? (pNextTxRate->
 297                                                           CurrMCS +
 298                                                           8) : pNextTxRate->
 299                                            CurrMCS;
 300                                        break;
 301                                case 7:
 302                                        LgCfg0.field.OFDMMCS7FBK =
 303                                            (pNextTxRate->Mode ==
 304                                             MODE_OFDM) ? (pNextTxRate->
 305                                                           CurrMCS +
 306                                                           8) : pNextTxRate->
 307                                            CurrMCS;
 308                                        break;
 309                                }
 310                        }
 311                        break;
 312                case 2: /*HT-MIX */
 313                case 3: /*HT-GF */
 314                        {
 315                                if ((pNextTxRate->Mode >= MODE_HTMIX)
 316                                    && (pCurrTxRate->CurrMCS !=
 317                                        pNextTxRate->CurrMCS)) {
 318                                        switch (pCurrTxRate->CurrMCS) {
 319                                        case 0:
 320                                                HtCfg0.field.HTMCS0FBK =
 321                                                    pNextTxRate->CurrMCS;
 322                                                break;
 323                                        case 1:
 324                                                HtCfg0.field.HTMCS1FBK =
 325                                                    pNextTxRate->CurrMCS;
 326                                                break;
 327                                        case 2:
 328                                                HtCfg0.field.HTMCS2FBK =
 329                                                    pNextTxRate->CurrMCS;
 330                                                break;
 331                                        case 3:
 332                                                HtCfg0.field.HTMCS3FBK =
 333                                                    pNextTxRate->CurrMCS;
 334                                                break;
 335                                        case 4:
 336                                                HtCfg0.field.HTMCS4FBK =
 337                                                    pNextTxRate->CurrMCS;
 338                                                break;
 339                                        case 5:
 340                                                HtCfg0.field.HTMCS5FBK =
 341                                                    pNextTxRate->CurrMCS;
 342                                                break;
 343                                        case 6:
 344                                                HtCfg0.field.HTMCS6FBK =
 345                                                    pNextTxRate->CurrMCS;
 346                                                break;
 347                                        case 7:
 348                                                HtCfg0.field.HTMCS7FBK =
 349                                                    pNextTxRate->CurrMCS;
 350                                                break;
 351                                        case 8:
 352                                                HtCfg1.field.HTMCS8FBK =
 353                                                    pNextTxRate->CurrMCS;
 354                                                break;
 355                                        case 9:
 356                                                HtCfg1.field.HTMCS9FBK =
 357                                                    pNextTxRate->CurrMCS;
 358                                                break;
 359                                        case 10:
 360                                                HtCfg1.field.HTMCS10FBK =
 361                                                    pNextTxRate->CurrMCS;
 362                                                break;
 363                                        case 11:
 364                                                HtCfg1.field.HTMCS11FBK =
 365                                                    pNextTxRate->CurrMCS;
 366                                                break;
 367                                        case 12:
 368                                                HtCfg1.field.HTMCS12FBK =
 369                                                    pNextTxRate->CurrMCS;
 370                                                break;
 371                                        case 13:
 372                                                HtCfg1.field.HTMCS13FBK =
 373                                                    pNextTxRate->CurrMCS;
 374                                                break;
 375                                        case 14:
 376                                                HtCfg1.field.HTMCS14FBK =
 377                                                    pNextTxRate->CurrMCS;
 378                                                break;
 379                                        case 15:
 380                                                HtCfg1.field.HTMCS15FBK =
 381                                                    pNextTxRate->CurrMCS;
 382                                                break;
 383                                        default:
 384                                                DBGPRINT(RT_DEBUG_ERROR,
 385                                                         ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n",
 386                                                          pCurrTxRate->
 387                                                          CurrMCS));
 388                                        }
 389                                }
 390                        }
 391                        break;
 392                }
 393
 394                pNextTxRate = pCurrTxRate;
 395        }
 396
 397        RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
 398        RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
 399        RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
 400        RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
 401}
 402
 403/*
 404        ========================================================================
 405
 406        Routine Description:
 407                Set MAC register value according operation mode.
 408                OperationMode AND bNonGFExist are for MM and GF Proteciton.
 409                If MM or GF mask is not set, those passing argument doesn't not take effect.
 410
 411                Operation mode meaning:
 412                = 0 : Pure HT, no preotection.
 413                = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
 414                = 0x10: No Transmission in 40M is protected.
 415                = 0x11: Transmission in both 40M and 20M shall be protected
 416                if (bNonGFExist)
 417                        we should choose not to use GF. But still set correct ASIC registers.
 418        ========================================================================
 419*/
 420void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
 421                       u16 OperationMode,
 422                       u8 SetMask,
 423                       IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist)
 424{
 425        PROT_CFG_STRUC ProtCfg, ProtCfg4;
 426        u32 Protect[6];
 427        u16 offset;
 428        u8 i;
 429        u32 MacReg = 0;
 430
 431        if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) {
 432                return;
 433        }
 434
 435        if (pAd->BATable.numDoneOriginator) {
 436                /* */
 437                /* enable the RTS/CTS to avoid channel collision */
 438                /* */
 439                SetMask = ALLN_SETPROTECT;
 440                OperationMode = 8;
 441        }
 442        /* Config ASIC RTS threshold register */
 443        RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
 444        MacReg &= 0xFF0000FF;
 445        /* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */
 446        if (((pAd->CommonCfg.BACapability.field.AmsduEnable) ||
 447             (pAd->CommonCfg.bAggregationCapable == TRUE))
 448            && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) {
 449                MacReg |= (0x1000 << 8);
 450        } else {
 451                MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
 452        }
 453
 454        RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
 455
 456        /* Initial common protection settings */
 457        RTMPZeroMemory(Protect, sizeof(Protect));
 458        ProtCfg4.word = 0;
 459        ProtCfg.word = 0;
 460        ProtCfg.field.TxopAllowGF40 = 1;
 461        ProtCfg.field.TxopAllowGF20 = 1;
 462        ProtCfg.field.TxopAllowMM40 = 1;
 463        ProtCfg.field.TxopAllowMM20 = 1;
 464        ProtCfg.field.TxopAllowOfdm = 1;
 465        ProtCfg.field.TxopAllowCck = 1;
 466        ProtCfg.field.RTSThEn = 1;
 467        ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
 468
 469        /* update PHY mode and rate */
 470        if (pAd->CommonCfg.Channel > 14)
 471                ProtCfg.field.ProtectRate = 0x4000;
 472        ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
 473
 474        /* Handle legacy(B/G) protection */
 475        if (bDisableBGProtect) {
 476                /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
 477                ProtCfg.field.ProtectCtrl = 0;
 478                Protect[0] = ProtCfg.word;
 479                Protect[1] = ProtCfg.word;
 480                pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
 481        } else {
 482                /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
 483                ProtCfg.field.ProtectCtrl = 0;  /* CCK do not need to be protected */
 484                Protect[0] = ProtCfg.word;
 485                ProtCfg.field.ProtectCtrl = ASIC_CTS;   /* OFDM needs using CCK to protect */
 486                Protect[1] = ProtCfg.word;
 487                pAd->FlgCtsEnabled = 1; /* CTS-self is used */
 488        }
 489
 490        /* Decide HT frame protection. */
 491        if ((SetMask & ALLN_SETPROTECT) != 0) {
 492                switch (OperationMode) {
 493                case 0x0:
 494                        /* NO PROTECT */
 495                        /* 1.All STAs in the BSS are 20/40 MHz HT */
 496                        /* 2. in ai 20/40MHz BSS */
 497                        /* 3. all STAs are 20MHz in a 20MHz BSS */
 498                        /* Pure HT. no protection. */
 499
 500                        /* MM20_PROT_CFG */
 501                        /*      Reserved (31:27) */
 502                        /*      PROT_TXOP(25:20) -- 010111 */
 503                        /*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
 504                        /*  PROT_CTRL(17:16) -- 00 (None) */
 505                        /*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
 506                        Protect[2] = 0x01744004;
 507
 508                        /* MM40_PROT_CFG */
 509                        /*      Reserved (31:27) */
 510                        /*      PROT_TXOP(25:20) -- 111111 */
 511                        /*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
 512                        /*  PROT_CTRL(17:16) -- 00 (None) */
 513                        /*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
 514                        Protect[3] = 0x03f44084;
 515
 516                        /* CF20_PROT_CFG */
 517                        /*      Reserved (31:27) */
 518                        /*      PROT_TXOP(25:20) -- 010111 */
 519                        /*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
 520                        /*  PROT_CTRL(17:16) -- 00 (None) */
 521                        /*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
 522                        Protect[4] = 0x01744004;
 523
 524                        /* CF40_PROT_CFG */
 525                        /*      Reserved (31:27) */
 526                        /*      PROT_TXOP(25:20) -- 111111 */
 527                        /*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
 528                        /*  PROT_CTRL(17:16) -- 00 (None) */
 529                        /*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
 530                        Protect[5] = 0x03f44084;
 531
 532                        if (bNonGFExist) {
 533                                /* PROT_NAV(19:18)  -- 01 (Short NAV protectiion) */
 534                                /* PROT_CTRL(17:16) -- 01 (RTS/CTS) */
 535                                Protect[4] = 0x01754004;
 536                                Protect[5] = 0x03f54084;
 537                        }
 538                        pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
 539                        break;
 540
 541                case 1:
 542                        /* This is "HT non-member protection mode." */
 543                        /* If there may be non-HT STAs my BSS */
 544                        ProtCfg.word = 0x01744004;      /* PROT_CTRL(17:16) : 0 (None) */
 545                        ProtCfg4.word = 0x03f44084;     /* duplicaet legacy 24M. BW set 1. */
 546                        if (OPSTATUS_TEST_FLAG
 547                            (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
 548                                ProtCfg.word = 0x01740003;      /*ERP use Protection bit is set, use protection rate at Clause 18.. */
 549                                ProtCfg4.word = 0x03f40003;     /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
 550                        }
 551                        /*Assign Protection method for 20&40 MHz packets */
 552                        ProtCfg.field.ProtectCtrl = ASIC_RTS;
 553                        ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
 554                        ProtCfg4.field.ProtectCtrl = ASIC_RTS;
 555                        ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
 556                        Protect[2] = ProtCfg.word;
 557                        Protect[3] = ProtCfg4.word;
 558                        Protect[4] = ProtCfg.word;
 559                        Protect[5] = ProtCfg4.word;
 560                        pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
 561                        break;
 562
 563                case 2:
 564                        /* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */
 565                        ProtCfg.word = 0x01744004;      /* PROT_CTRL(17:16) : 0 (None) */
 566                        ProtCfg4.word = 0x03f44084;     /* duplicaet legacy 24M. BW set 1. */
 567
 568                        /*Assign Protection method for 40MHz packets */
 569                        ProtCfg4.field.ProtectCtrl = ASIC_RTS;
 570                        ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
 571                        Protect[2] = ProtCfg.word;
 572                        Protect[3] = ProtCfg4.word;
 573                        if (bNonGFExist) {
 574                                ProtCfg.field.ProtectCtrl = ASIC_RTS;
 575                                ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
 576                        }
 577                        Protect[4] = ProtCfg.word;
 578                        Protect[5] = ProtCfg4.word;
 579
 580                        pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
 581                        break;
 582
 583                case 3:
 584                        /* HT mixed mode.        PROTECT ALL! */
 585                        /* Assign Rate */
 586                        ProtCfg.word = 0x01744004;      /*duplicaet legacy 24M. BW set 1. */
 587                        ProtCfg4.word = 0x03f44084;
 588                        /* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */
 589                        if (OPSTATUS_TEST_FLAG
 590                            (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
 591                                ProtCfg.word = 0x01740003;      /*ERP use Protection bit is set, use protection rate at Clause 18.. */
 592                                ProtCfg4.word = 0x03f40003;     /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */
 593                        }
 594                        /*Assign Protection method for 20&40 MHz packets */
 595                        ProtCfg.field.ProtectCtrl = ASIC_RTS;
 596                        ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
 597                        ProtCfg4.field.ProtectCtrl = ASIC_RTS;
 598                        ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
 599                        Protect[2] = ProtCfg.word;
 600                        Protect[3] = ProtCfg4.word;
 601                        Protect[4] = ProtCfg.word;
 602                        Protect[5] = ProtCfg4.word;
 603                        pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
 604                        break;
 605
 606                case 8:
 607                        /* Special on for Atheros problem n chip. */
 608                        Protect[2] = 0x01754004;
 609                        Protect[3] = 0x03f54084;
 610                        Protect[4] = 0x01754004;
 611                        Protect[5] = 0x03f54084;
 612                        pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
 613                        break;
 614                }
 615        }
 616
 617        offset = CCK_PROT_CFG;
 618        for (i = 0; i < 6; i++) {
 619                if ((SetMask & (1 << i))) {
 620                        RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]);
 621                }
 622        }
 623}
 624
 625/*
 626        ==========================================================================
 627        Description:
 628
 629        IRQL = PASSIVE_LEVEL
 630        IRQL = DISPATCH_LEVEL
 631
 632        ==========================================================================
 633 */
 634void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan)
 635{
 636        unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
 637        char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */
 638        u8 index;
 639        u32 Value = 0;  /*BbpReg, Value; */
 640        struct rt_rtmp_rf_regs *RFRegTable;
 641        u8 RFValue;
 642
 643        RFValue = 0;
 644        /* Search Tx power value */
 645        /* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */
 646        /* in ChannelList, so use TxPower array instead. */
 647        /* */
 648        for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) {
 649                if (Channel == pAd->TxPower[index].Channel) {
 650                        TxPwer = pAd->TxPower[index].Power;
 651                        TxPwer2 = pAd->TxPower[index].Power2;
 652                        break;
 653                }
 654        }
 655
 656        if (index == MAX_NUM_OF_CHANNELS) {
 657                DBGPRINT(RT_DEBUG_ERROR,
 658                         ("AsicSwitchChannel: Can't find the Channel#%d \n",
 659                          Channel));
 660        }
 661#ifdef RT30xx
 662        /* The RF programming sequence is difference between 3xxx and 2xxx */
 663        if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
 664            && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)
 665                || (pAd->RfIcType == RFIC_3021)
 666                || (pAd->RfIcType == RFIC_3022))) {
 667                /* modify by WY for Read RF Reg. error */
 668
 669                for (index = 0; index < NUM_OF_3020_CHNL; index++) {
 670                        if (Channel == FreqItems3020[index].Channel) {
 671                                /* Programming channel parameters */
 672                                RT30xxWriteRFRegister(pAd, RF_R02,
 673                                                      FreqItems3020[index].N);
 674                                RT30xxWriteRFRegister(pAd, RF_R03,
 675                                                      FreqItems3020[index].K);
 676                                RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
 677                                RFValue =
 678                                    (RFValue & 0xFC) | FreqItems3020[index].R;
 679                                RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
 680
 681                                /* Set Tx0 Power */
 682                                RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
 683                                RFValue = (RFValue & 0xE0) | TxPwer;
 684                                RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
 685
 686                                /* Set Tx1 Power */
 687                                RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
 688                                RFValue = (RFValue & 0xE0) | TxPwer2;
 689                                RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
 690
 691                                /* Tx/Rx Stream setting */
 692                                RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
 693                                /*if (IS_RT3090(pAd)) */
 694                                /*      RFValue |= 0x01; // Enable RF block. */
 695                                RFValue &= 0x03;        /*clear bit[7~2] */
 696                                if (pAd->Antenna.field.TxPath == 1)
 697                                        RFValue |= 0xA0;
 698                                else if (pAd->Antenna.field.TxPath == 2)
 699                                        RFValue |= 0x80;
 700                                if (pAd->Antenna.field.RxPath == 1)
 701                                        RFValue |= 0x50;
 702                                else if (pAd->Antenna.field.RxPath == 2)
 703                                        RFValue |= 0x40;
 704                                RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
 705
 706                                /* Set RF offset */
 707                                RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
 708                                RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
 709                                RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
 710
 711                                /* Set BW */
 712                                if (!bScan
 713                                    && (pAd->CommonCfg.BBPCurrentBW == BW_40)) {
 714                                        RFValue = pAd->Mlme.CaliBW40RfR24;
 715                                        /*DISABLE_11N_CHECK(pAd); */
 716                                } else {
 717                                        RFValue = pAd->Mlme.CaliBW20RfR24;
 718                                }
 719                                RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
 720                                RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
 721
 722                                /* Enable RF tuning */
 723                                RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
 724                                RFValue = RFValue | 0x1;
 725                                RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
 726
 727                                /* latch channel for future usage. */
 728                                pAd->LatchRfRegs.Channel = Channel;
 729
 730                                DBGPRINT(RT_DEBUG_TRACE,
 731                                         ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
 732                                          Channel, pAd->RfIcType, TxPwer,
 733                                          TxPwer2, pAd->Antenna.field.TxPath,
 734                                          FreqItems3020[index].N,
 735                                          FreqItems3020[index].K,
 736                                          FreqItems3020[index].R));
 737
 738                                break;
 739                        }
 740                }
 741        } else
 742#endif /* RT30xx // */
 743        {
 744                RFRegTable = RF2850RegTable;
 745                switch (pAd->RfIcType) {
 746                case RFIC_2820:
 747                case RFIC_2850:
 748                case RFIC_2720:
 749                case RFIC_2750:
 750
 751                        for (index = 0; index < NUM_OF_2850_CHNL; index++) {
 752                                if (Channel == RFRegTable[index].Channel) {
 753                                        R2 = RFRegTable[index].R2;
 754                                        if (pAd->Antenna.field.TxPath == 1) {
 755                                                R2 |= 0x4000;   /* If TXpath is 1, bit 14 = 1; */
 756                                        }
 757
 758                                        if (pAd->Antenna.field.RxPath == 2) {
 759                                                R2 |= 0x40;     /* write 1 to off Rxpath. */
 760                                        } else if (pAd->Antenna.field.RxPath ==
 761                                                   1) {
 762                                                R2 |= 0x20040;  /* write 1 to off RxPath */
 763                                        }
 764
 765                                        if (Channel > 14) {
 766                                                /* initialize R3, R4 */
 767                                                R3 = (RFRegTable[index].
 768                                                      R3 & 0xffffc1ff);
 769                                                R4 = (RFRegTable[index].
 770                                                      R4 & (~0x001f87c0)) |
 771                                                    (pAd->RfFreqOffset << 15);
 772
 773                                                /* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */
 774                                                /* R3 */
 775                                                if ((TxPwer >= -7)
 776                                                    && (TxPwer < 0)) {
 777                                                        TxPwer = (7 + TxPwer);
 778                                                        TxPwer =
 779                                                            (TxPwer >
 780                                                             0xF) ? (0xF)
 781                                                            : (TxPwer);
 782                                                        R3 |= (TxPwer << 10);
 783                                                        DBGPRINT(RT_DEBUG_ERROR,
 784                                                                 ("AsicSwitchChannel: TxPwer=%d \n",
 785                                                                  TxPwer));
 786                                                } else {
 787                                                        TxPwer =
 788                                                            (TxPwer >
 789                                                             0xF) ? (0xF)
 790                                                            : (TxPwer);
 791                                                        R3 |=
 792                                                            (TxPwer << 10) | (1
 793                                                                              <<
 794                                                                              9);
 795                                                }
 796
 797                                                /* R4 */
 798                                                if ((TxPwer2 >= -7)
 799                                                    && (TxPwer2 < 0)) {
 800                                                        TxPwer2 = (7 + TxPwer2);
 801                                                        TxPwer2 =
 802                                                            (TxPwer2 >
 803                                                             0xF) ? (0xF)
 804                                                            : (TxPwer2);
 805                                                        R4 |= (TxPwer2 << 7);
 806                                                        DBGPRINT(RT_DEBUG_ERROR,
 807                                                                 ("AsicSwitchChannel: TxPwer2=%d \n",
 808                                                                  TxPwer2));
 809                                                } else {
 810                                                        TxPwer2 =
 811                                                            (TxPwer2 >
 812                                                             0xF) ? (0xF)
 813                                                            : (TxPwer2);
 814                                                        R4 |=
 815                                                            (TxPwer2 << 7) | (1
 816                                                                              <<
 817                                                                              6);
 818                                                }
 819                                        } else {
 820                                                R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9);       /* set TX power0 */
 821                                                R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6);       /* Set freq Offset & TxPwr1 */
 822                                        }
 823
 824                                        /* Based on BBP current mode before changing RF channel. */
 825                                        if (!bScan
 826                                            && (pAd->CommonCfg.BBPCurrentBW ==
 827                                                BW_40)) {
 828                                                R4 |= 0x200000;
 829                                        }
 830                                        /* Update variables */
 831                                        pAd->LatchRfRegs.Channel = Channel;
 832                                        pAd->LatchRfRegs.R1 =
 833                                            RFRegTable[index].R1;
 834                                        pAd->LatchRfRegs.R2 = R2;
 835                                        pAd->LatchRfRegs.R3 = R3;
 836                                        pAd->LatchRfRegs.R4 = R4;
 837
 838                                        /* Set RF value 1's set R3[bit2] = [0] */
 839                                        RTMP_RF_IO_WRITE32(pAd,
 840                                                           pAd->LatchRfRegs.R1);
 841                                        RTMP_RF_IO_WRITE32(pAd,
 842                                                           pAd->LatchRfRegs.R2);
 843                                        RTMP_RF_IO_WRITE32(pAd,
 844                                                           (pAd->LatchRfRegs.
 845                                                            R3 & (~0x04)));
 846                                        RTMP_RF_IO_WRITE32(pAd,
 847                                                           pAd->LatchRfRegs.R4);
 848
 849                                        RTMPusecDelay(200);
 850
 851                                        /* Set RF value 2's set R3[bit2] = [1] */
 852                                        RTMP_RF_IO_WRITE32(pAd,
 853                                                           pAd->LatchRfRegs.R1);
 854                                        RTMP_RF_IO_WRITE32(pAd,
 855                                                           pAd->LatchRfRegs.R2);
 856                                        RTMP_RF_IO_WRITE32(pAd,
 857                                                           (pAd->LatchRfRegs.
 858                                                            R3 | 0x04));
 859                                        RTMP_RF_IO_WRITE32(pAd,
 860                                                           pAd->LatchRfRegs.R4);
 861
 862                                        RTMPusecDelay(200);
 863
 864                                        /* Set RF value 3's set R3[bit2] = [0] */
 865                                        RTMP_RF_IO_WRITE32(pAd,
 866                                                           pAd->LatchRfRegs.R1);
 867                                        RTMP_RF_IO_WRITE32(pAd,
 868                                                           pAd->LatchRfRegs.R2);
 869                                        RTMP_RF_IO_WRITE32(pAd,
 870                                                           (pAd->LatchRfRegs.
 871                                                            R3 & (~0x04)));
 872                                        RTMP_RF_IO_WRITE32(pAd,
 873                                                           pAd->LatchRfRegs.R4);
 874
 875                                        break;
 876                                }
 877                        }
 878                        break;
 879
 880                default:
 881                        break;
 882                }
 883
 884                DBGPRINT(RT_DEBUG_TRACE,
 885                         ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
 886                          Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9,
 887                          (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath,
 888                          pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2,
 889                          pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4));
 890        }
 891
 892        /* Change BBP setting during siwtch from a->g, g->a */
 893        if (Channel <= 14) {
 894                unsigned long TxPinCfg = 0x00050F0A;    /*Gary 2007/08/09 0x050A0A */
 895
 896                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
 897                                             (0x37 - GET_LNA_GAIN(pAd)));
 898                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
 899                                             (0x37 - GET_LNA_GAIN(pAd)));
 900                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
 901                                             (0x37 - GET_LNA_GAIN(pAd)));
 902                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);  /*(0x44 - GET_LNA_GAIN(pAd)));    // According the Rory's suggestion to solve the middle range issue. */
 903                /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */
 904
 905                /* Rx High power VGA offset for LNA select */
 906                if (pAd->NicConfig2.field.ExternalLNAForG) {
 907                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
 908                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
 909                } else {
 910                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
 911                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
 912                }
 913
 914                /* 5G band selection PIN, bit1 and bit2 are complement */
 915                RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
 916                Value &= (~0x6);
 917                Value |= (0x04);
 918                RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
 919
 920                /* Turn off unused PA or LNA when only 1T or 1R */
 921                if (pAd->Antenna.field.TxPath == 1) {
 922                        TxPinCfg &= 0xFFFFFFF3;
 923                }
 924                if (pAd->Antenna.field.RxPath == 1) {
 925                        TxPinCfg &= 0xFFFFF3FF;
 926                }
 927
 928                RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
 929
 930#if defined(RT3090) || defined(RT3390)
 931                /* PCIe PHY Transmit attenuation adjustment */
 932                if (IS_RT3090A(pAd) || IS_RT3390(pAd)) {
 933                        TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {
 934                        .word = 0};
 935
 936                        RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
 937                                       &TxAttenuationCtrl.word);
 938
 939                        if (Channel == 14)      /* Channel #14 */
 940                        {
 941                                TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1;       /* Enable PCIe PHY Tx attenuation */
 942                                TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4;    /* 9/16 full drive level */
 943                        } else  /* Channel #1~#13 */
 944                        {
 945                                TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0;       /* Disable PCIe PHY Tx attenuation */
 946                                TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0;    /* n/a */
 947                        }
 948
 949                        RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
 950                                        TxAttenuationCtrl.word);
 951                }
 952#endif
 953        } else {
 954                unsigned long TxPinCfg = 0x00050F05;    /*Gary 2007/8/9 0x050505 */
 955
 956                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
 957                                             (0x37 - GET_LNA_GAIN(pAd)));
 958                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
 959                                             (0x37 - GET_LNA_GAIN(pAd)));
 960                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
 961                                             (0x37 - GET_LNA_GAIN(pAd)));
 962                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);  /*(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue. */
 963                RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
 964
 965                /* Rx High power VGA offset for LNA select */
 966                if (pAd->NicConfig2.field.ExternalLNAForA) {
 967                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
 968                } else {
 969                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
 970                }
 971
 972                /* 5G band selection PIN, bit1 and bit2 are complement */
 973                RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
 974                Value &= (~0x6);
 975                Value |= (0x02);
 976                RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
 977
 978                /* Turn off unused PA or LNA when only 1T or 1R */
 979                if (pAd->Antenna.field.TxPath == 1) {
 980                        TxPinCfg &= 0xFFFFFFF3;
 981                }
 982                if (pAd->Antenna.field.RxPath == 1) {
 983                        TxPinCfg &= 0xFFFFF3FF;
 984                }
 985
 986                RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
 987
 988        }
 989
 990        /* R66 should be set according to Channel and use 20MHz when scanning */
 991        /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */
 992        if (bScan)
 993                RTMPSetAGCInitValue(pAd, BW_20);
 994        else
 995                RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
 996
 997        /* */
 998        /* On 11A, We should delay and wait RF/BBP to be stable */
 999        /* and the appropriate time should be 1000 micro seconds */
1000        /* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */
1001        /* */
1002        RTMPusecDelay(1000);
1003}
1004
1005void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd)
1006{
1007        BBP_CSR_CFG_STRUC BbpCsr;
1008        DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n"));
1009        /* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */
1010        RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
1011        BbpCsr.field.Busy = 0;
1012        RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
1013}
1014
1015/*
1016        ==========================================================================
1017        Description:
1018                This function is required for 2421 only, and should not be used during
1019                site survey. It's only required after NIC decided to stay at a channel
1020                for a longer period.
1021                When this function is called, it's always after AsicSwitchChannel().
1022
1023        IRQL = PASSIVE_LEVEL
1024        IRQL = DISPATCH_LEVEL
1025
1026        ==========================================================================
1027 */
1028void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
1029{
1030}
1031
1032void AsicRfTuningExec(void *SystemSpecific1,
1033                      void *FunctionContext,
1034                      void *SystemSpecific2, void *SystemSpecific3)
1035{
1036}
1037
1038/*
1039        ==========================================================================
1040        Description:
1041                Gives CCK TX rate 2 more dB TX power.
1042                This routine works only in LINK UP in INFRASTRUCTURE mode.
1043
1044                calculate desired Tx power in RF R3.Tx0~5,      should consider -
1045                0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
1046                1. TxPowerPercentage
1047                2. auto calibration based on TSSI feedback
1048                3. extra 2 db for CCK
1049                4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
1050
1051        NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
1052                it should be called AFTER MlmeDynamicTxRatSwitching()
1053        ==========================================================================
1054 */
1055void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd)
1056{
1057        int i, j;
1058        char DeltaPwr = 0;
1059        BOOLEAN bAutoTxAgc = FALSE;
1060        u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
1061        u8 BbpR1 = 0, BbpR49 = 0, idx;
1062        char *pTxAgcCompensate;
1063        unsigned long TxPwr[5];
1064        char Value;
1065        char Rssi = -127;
1066
1067        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1068#ifdef RTMP_MAC_PCI
1069            (pAd->bPCIclkOff == TRUE) ||
1070#endif /* RTMP_MAC_PCI // */
1071            RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
1072            RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1073                return;
1074
1075        Rssi = RTMPMaxRssi(pAd,
1076                           pAd->StaCfg.RssiSample.AvgRssi0,
1077                           pAd->StaCfg.RssiSample.AvgRssi1,
1078                           pAd->StaCfg.RssiSample.AvgRssi2);
1079
1080        if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1081                if (pAd->CommonCfg.CentralChannel > 14) {
1082                        TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
1083                        TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
1084                        TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
1085                        TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
1086                        TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
1087                } else {
1088                        TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
1089                        TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
1090                        TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
1091                        TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
1092                        TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
1093                }
1094        } else {
1095                if (pAd->CommonCfg.Channel > 14) {
1096                        TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
1097                        TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
1098                        TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
1099                        TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
1100                        TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
1101                } else {
1102                        TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
1103                        TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
1104                        TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
1105                        TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
1106                        TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
1107                }
1108        }
1109
1110        /* TX power compensation for temperature variation based on TSSI. try every 4 second */
1111        if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) {
1112                if (pAd->CommonCfg.Channel <= 14) {
1113                        /* bg channel */
1114                        bAutoTxAgc = pAd->bAutoTxAgcG;
1115                        TssiRef = pAd->TssiRefG;
1116                        pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
1117                        pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
1118                        TxAgcStep = pAd->TxAgcStepG;
1119                        pTxAgcCompensate = &pAd->TxAgcCompensateG;
1120                } else {
1121                        /* a channel */
1122                        bAutoTxAgc = pAd->bAutoTxAgcA;
1123                        TssiRef = pAd->TssiRefA;
1124                        pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
1125                        pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
1126                        TxAgcStep = pAd->TxAgcStepA;
1127                        pTxAgcCompensate = &pAd->TxAgcCompensateA;
1128                }
1129
1130                if (bAutoTxAgc) {
1131                        /* BbpR1 is unsigned char */
1132                        RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
1133
1134                        /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
1135                        /* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
1136                        /* step value is defined in pAd->TxAgcStepG for tx power value */
1137
1138                        /* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
1139                        /* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1140                           above value are examined in mass factory production */
1141                        /*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
1142
1143                        /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
1144                        /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
1145                        /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
1146
1147                        if (BbpR49 > pTssiMinusBoundary[1]) {
1148                                /* Reading is larger than the reference value */
1149                                /* check for how large we need to decrease the Tx power */
1150                                for (idx = 1; idx < 5; idx++) {
1151                                        if (BbpR49 <= pTssiMinusBoundary[idx])  /* Found the range */
1152                                                break;
1153                                }
1154                                /* The index is the step we should decrease, idx = 0 means there is nothing to compensate */
1155/*                              if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */
1156                                *pTxAgcCompensate = -(TxAgcStep * (idx - 1));
1157/*                              else */
1158/*                                      *pTxAgcCompensate = -((u8)R3); */
1159
1160                                DeltaPwr += (*pTxAgcCompensate);
1161                                DBGPRINT(RT_DEBUG_TRACE,
1162                                         ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
1163                                          BbpR49, TssiRef, TxAgcStep, idx - 1));
1164                        } else if (BbpR49 < pTssiPlusBoundary[1]) {
1165                                /* Reading is smaller than the reference value */
1166                                /* check for how large we need to increase the Tx power */
1167                                for (idx = 1; idx < 5; idx++) {
1168                                        if (BbpR49 >= pTssiPlusBoundary[idx])   /* Found the range */
1169                                                break;
1170                                }
1171                                /* The index is the step we should increase, idx = 0 means there is nothing to compensate */
1172                                *pTxAgcCompensate = TxAgcStep * (idx - 1);
1173                                DeltaPwr += (*pTxAgcCompensate);
1174                                DBGPRINT(RT_DEBUG_TRACE,
1175                                         ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1176                                          BbpR49, TssiRef, TxAgcStep, idx - 1));
1177                        } else {
1178                                *pTxAgcCompensate = 0;
1179                                DBGPRINT(RT_DEBUG_TRACE,
1180                                         ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1181                                          BbpR49, TssiRef, TxAgcStep, 0));
1182                        }
1183                }
1184        } else {
1185                if (pAd->CommonCfg.Channel <= 14) {
1186                        bAutoTxAgc = pAd->bAutoTxAgcG;
1187                        pTxAgcCompensate = &pAd->TxAgcCompensateG;
1188                } else {
1189                        bAutoTxAgc = pAd->bAutoTxAgcA;
1190                        pTxAgcCompensate = &pAd->TxAgcCompensateA;
1191                }
1192
1193                if (bAutoTxAgc)
1194                        DeltaPwr += (*pTxAgcCompensate);
1195        }
1196
1197        RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
1198        BbpR1 &= 0xFC;
1199
1200        /* calculate delta power based on the percentage specified from UI */
1201        /* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */
1202        /* We lower TX power here according to the percentage specified from UI */
1203        if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)     /* AUTO TX POWER control */
1204        {
1205                {
1206                        /* to patch high power issue with some APs, like Belkin N1. */
1207                        if (Rssi > -35) {
1208                                BbpR1 |= 0x02;  /* DeltaPwr -= 12; */
1209                        } else if (Rssi > -40) {
1210                                BbpR1 |= 0x01;  /* DeltaPwr -= 6; */
1211                        } else;
1212                }
1213        } else if (pAd->CommonCfg.TxPowerPercentage > 90)       /* 91 ~ 100% & AUTO, treat as 100% in terms of mW */
1214                ;
1215        else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW               // DeltaPwr -= 1; */
1216        {
1217                DeltaPwr -= 1;
1218        } else if (pAd->CommonCfg.TxPowerPercentage > 30)       /* 31 ~ 60%, treat as 50% in terms of mW               // DeltaPwr -= 3; */
1219        {
1220                DeltaPwr -= 3;
1221        } else if (pAd->CommonCfg.TxPowerPercentage > 15)       /* 16 ~ 30%, treat as 25% in terms of mW               // DeltaPwr -= 6; */
1222        {
1223                BbpR1 |= 0x01;
1224        } else if (pAd->CommonCfg.TxPowerPercentage > 9)        /* 10 ~ 15%, treat as 12.5% in terms of mW             // DeltaPwr -= 9; */
1225        {
1226                BbpR1 |= 0x01;
1227                DeltaPwr -= 3;
1228        } else                  /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW             // DeltaPwr -= 12; */
1229        {
1230                BbpR1 |= 0x02;
1231        }
1232
1233        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
1234
1235        /* reset different new tx power for different TX rate */
1236        for (i = 0; i < 5; i++) {
1237                if (TxPwr[i] != 0xffffffff) {
1238                        for (j = 0; j < 8; j++) {
1239                                Value = (char)((TxPwr[i] >> j * 4) & 0x0F);     /* 0 ~ 15 */
1240
1241                                if ((Value + DeltaPwr) < 0) {
1242                                        Value = 0;      /* min */
1243                                } else if ((Value + DeltaPwr) > 0xF) {
1244                                        Value = 0xF;    /* max */
1245                                } else {
1246                                        Value += DeltaPwr;      /* temperature compensation */
1247                                }
1248
1249                                /* fill new value to CSR offset */
1250                                TxPwr[i] =
1251                                    (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value
1252                                                                           << j
1253                                                                           * 4);
1254                        }
1255
1256                        /* write tx power value to CSR */
1257                        /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
1258                           TX power for OFDM 6M/9M
1259                           TX power for CCK5.5M/11M
1260                           TX power for CCK1M/2M */
1261                        /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
1262                        RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]);
1263                }
1264        }
1265
1266}
1267
1268/*
1269        ==========================================================================
1270        Description:
1271                put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
1272                automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
1273                the wakeup timer timeout. Driver has to issue a separate command to wake
1274                PHY up.
1275
1276        IRQL = DISPATCH_LEVEL
1277
1278        ==========================================================================
1279 */
1280void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
1281                             u16 TbttNumToNextWakeUp)
1282{
1283        RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
1284}
1285
1286/*
1287        ==========================================================================
1288        Description:
1289                AsicForceWakeup() is used whenever manual wakeup is required
1290                AsicForceSleep() should only be used when not in INFRA BSS. When
1291                in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
1292        ==========================================================================
1293 */
1294void AsicForceSleep(struct rt_rtmp_adapter *pAd)
1295{
1296
1297}
1298
1299/*
1300        ==========================================================================
1301        Description:
1302                AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
1303                expired.
1304
1305        IRQL = PASSIVE_LEVEL
1306        IRQL = DISPATCH_LEVEL
1307        ==========================================================================
1308 */
1309void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
1310{
1311        DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
1312        RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
1313}
1314
1315/*
1316        ==========================================================================
1317        Description:
1318                Set My BSSID
1319
1320        IRQL = DISPATCH_LEVEL
1321
1322        ==========================================================================
1323 */
1324void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid)
1325{
1326        unsigned long Addr4;
1327        DBGPRINT(RT_DEBUG_TRACE,
1328                 ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0],
1329                  pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5]));
1330
1331        Addr4 = (unsigned long)(pBssid[0]) |
1332            (unsigned long)(pBssid[1] << 8) |
1333            (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24);
1334        RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
1335
1336        Addr4 = 0;
1337        /* always one BSSID in STA mode */
1338        Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8);
1339
1340        RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
1341}
1342
1343void AsicSetMcastWC(struct rt_rtmp_adapter *pAd)
1344{
1345        struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID];
1346        u16 offset;
1347
1348        pEntry->Sst = SST_ASSOC;
1349        pEntry->Aid = MCAST_WCID;       /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */
1350        pEntry->PsMode = PWR_ACTIVE;
1351        pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
1352        offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
1353}
1354
1355/*
1356        ==========================================================================
1357        Description:
1358
1359        IRQL = DISPATCH_LEVEL
1360
1361        ==========================================================================
1362 */
1363void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid)
1364{
1365        unsigned long Addr0 = 0x0, Addr1 = 0x0;
1366        unsigned long offset;
1367
1368        DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid));
1369        offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
1370        RTMP_IO_WRITE32(pAd, offset, Addr0);
1371        offset += 4;
1372        RTMP_IO_WRITE32(pAd, offset, Addr1);
1373}
1374
1375/*
1376        ==========================================================================
1377        Description:
1378
1379        IRQL = DISPATCH_LEVEL
1380
1381        ==========================================================================
1382 */
1383void AsicEnableRDG(struct rt_rtmp_adapter *pAd)
1384{
1385        TX_LINK_CFG_STRUC TxLinkCfg;
1386        u32 Data = 0;
1387
1388        RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1389        TxLinkCfg.field.TxRDGEn = 1;
1390        RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1391
1392        RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1393        Data &= 0xFFFFFF00;
1394        Data |= 0x80;
1395        RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1396
1397        /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */
1398}
1399
1400/*
1401        ==========================================================================
1402        Description:
1403
1404        IRQL = DISPATCH_LEVEL
1405
1406        ==========================================================================
1407 */
1408void AsicDisableRDG(struct rt_rtmp_adapter *pAd)
1409{
1410        TX_LINK_CFG_STRUC TxLinkCfg;
1411        u32 Data = 0;
1412
1413        RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1414        TxLinkCfg.field.TxRDGEn = 0;
1415        RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1416
1417        RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1418
1419        Data &= 0xFFFFFF00;
1420        /*Data  |= 0x20; */
1421#ifndef WIFI_TEST
1422        /*if ( pAd->CommonCfg.bEnableTxBurst ) */
1423        /*      Data |= 0x60; // for performance issue not set the TXOP to 0 */
1424#endif
1425        if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
1426            && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
1427            ) {
1428                /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
1429                if (pAd->CommonCfg.bEnableTxBurst)
1430                        Data |= 0x20;
1431        }
1432        RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1433}
1434
1435/*
1436        ==========================================================================
1437        Description:
1438
1439        IRQL = PASSIVE_LEVEL
1440        IRQL = DISPATCH_LEVEL
1441
1442        ==========================================================================
1443 */
1444void AsicDisableSync(struct rt_rtmp_adapter *pAd)
1445{
1446        BCN_TIME_CFG_STRUC csr;
1447
1448        DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
1449
1450        /* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */
1451        /*                        that NIC will never wakes up because TSF stops and no more */
1452        /*                        TBTT interrupts */
1453        pAd->TbttTickCount = 0;
1454        RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1455        csr.field.bBeaconGen = 0;
1456        csr.field.bTBTTEnable = 0;
1457        csr.field.TsfSyncMode = 0;
1458        csr.field.bTsfTicking = 0;
1459        RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1460
1461}
1462
1463/*
1464        ==========================================================================
1465        Description:
1466
1467        IRQL = DISPATCH_LEVEL
1468
1469        ==========================================================================
1470 */
1471void AsicEnableBssSync(struct rt_rtmp_adapter *pAd)
1472{
1473        BCN_TIME_CFG_STRUC csr;
1474
1475        DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
1476
1477        RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1478/*      RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */
1479        {
1480                csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;    /* ASIC register in units of 1/16 TU */
1481                csr.field.bTsfTicking = 1;
1482                csr.field.TsfSyncMode = 1;      /* sync TSF in INFRASTRUCTURE mode */
1483                csr.field.bBeaconGen = 0;       /* do NOT generate BEACON */
1484                csr.field.bTBTTEnable = 1;
1485        }
1486        RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1487}
1488
1489/*
1490        ==========================================================================
1491        Description:
1492        Note:
1493                BEACON frame in shared memory should be built ok before this routine
1494                can be called. Otherwise, a garbage frame maybe transmitted out every
1495                Beacon period.
1496
1497        IRQL = DISPATCH_LEVEL
1498
1499        ==========================================================================
1500 */
1501void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd)
1502{
1503        BCN_TIME_CFG_STRUC csr9;
1504        u8 *ptr;
1505        u32 i;
1506
1507        DBGPRINT(RT_DEBUG_TRACE,
1508                 ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n",
1509                  pAd->BeaconTxWI.MPDUtotalByteCount));
1510
1511        RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
1512        csr9.field.bBeaconGen = 0;
1513        csr9.field.bTBTTEnable = 0;
1514        csr9.field.bTsfTicking = 0;
1515        RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1516
1517#ifdef RTMP_MAC_PCI
1518        /* move BEACON TXD and frame content to on-chip memory */
1519        ptr = (u8 *)& pAd->BeaconTxWI;
1520        for (i = 0; i < TXWI_SIZE; i += 4)      /* 16-byte TXWI field */
1521        {
1522                u32 longptr =
1523                    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
1524                    (*(ptr + 3) << 24);
1525                RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1526                ptr += 4;
1527        }
1528
1529        /* start right after the 16-byte TXWI field */
1530        ptr = pAd->BeaconBuf;
1531        for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) {
1532                u32 longptr =
1533                    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
1534                    (*(ptr + 3) << 24);
1535                RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1536                ptr += 4;
1537        }
1538#endif /* RTMP_MAC_PCI // */
1539#ifdef RTMP_MAC_USB
1540        /* move BEACON TXD and frame content to on-chip memory */
1541        ptr = (u8 *)& pAd->BeaconTxWI;
1542        for (i = 0; i < TXWI_SIZE; i += 2)      /* 16-byte TXWI field */
1543        {
1544                /*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
1545                /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */
1546                RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
1547                ptr += 2;
1548        }
1549
1550        /* start right after the 16-byte TXWI field */
1551        ptr = pAd->BeaconBuf;
1552        for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) {
1553                /*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
1554                /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */
1555                RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
1556                ptr += 2;
1557        }
1558#endif /* RTMP_MAC_USB // */
1559
1560        /* */
1561        /* For Wi-Fi faily generated beacons between participating stations. */
1562        /* Set TBTT phase adaptive adjustment step to 8us (default 16us) */
1563        /* don't change settings 2006-5- by Jerry */
1564        /*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */
1565
1566        /* start sending BEACON */
1567        csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;   /* ASIC register in units of 1/16 TU */
1568        csr9.field.bTsfTicking = 1;
1569        csr9.field.TsfSyncMode = 2;     /* sync TSF in IBSS mode */
1570        csr9.field.bTBTTEnable = 1;
1571        csr9.field.bBeaconGen = 1;
1572        RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1573}
1574
1575/*
1576        ==========================================================================
1577        Description:
1578
1579        IRQL = PASSIVE_LEVEL
1580        IRQL = DISPATCH_LEVEL
1581
1582        ==========================================================================
1583 */
1584void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm)
1585{
1586        EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
1587        AC_TXOP_CSR0_STRUC csr0;
1588        AC_TXOP_CSR1_STRUC csr1;
1589        AIFSN_CSR_STRUC AifsnCsr;
1590        CWMIN_CSR_STRUC CwminCsr;
1591        CWMAX_CSR_STRUC CwmaxCsr;
1592        int i;
1593
1594        Ac0Cfg.word = 0;
1595        Ac1Cfg.word = 0;
1596        Ac2Cfg.word = 0;
1597        Ac3Cfg.word = 0;
1598        if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) {
1599                DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n"));
1600                OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1601                for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
1602                        if (pAd->MacTab.Content[i].ValidAsCLI
1603                            || pAd->MacTab.Content[i].ValidAsApCli)
1604                                CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.
1605                                                         Content[i],
1606                                                         fCLIENT_STATUS_WMM_CAPABLE);
1607                }
1608
1609                /*======================================================== */
1610                /*      MAC Register has a copy . */
1611                /*======================================================== */
1612/*#ifndef WIFI_TEST */
1613                if (pAd->CommonCfg.bEnableTxBurst) {
1614                        /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
1615                        Ac0Cfg.field.AcTxop = 0x20;     /* Suggest by John for TxBurst in HT Mode */
1616                } else
1617                        Ac0Cfg.field.AcTxop = 0;        /* QID_AC_BE */
1618/*#else */
1619/*              Ac0Cfg.field.AcTxop = 0;        // QID_AC_BE */
1620/*#endif */
1621                Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
1622                Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
1623                Ac0Cfg.field.Aifsn = 2;
1624                RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1625
1626                Ac1Cfg.field.AcTxop = 0;        /* QID_AC_BK */
1627                Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
1628                Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
1629                Ac1Cfg.field.Aifsn = 2;
1630                RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1631
1632                if (pAd->CommonCfg.PhyMode == PHY_11B) {
1633                        Ac2Cfg.field.AcTxop = 192;      /* AC_VI: 192*32us ~= 6ms */
1634                        Ac3Cfg.field.AcTxop = 96;       /* AC_VO: 96*32us  ~= 3ms */
1635                } else {
1636                        Ac2Cfg.field.AcTxop = 96;       /* AC_VI: 96*32us ~= 3ms */
1637                        Ac3Cfg.field.AcTxop = 48;       /* AC_VO: 48*32us ~= 1.5ms */
1638                }
1639                Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
1640                Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
1641                Ac2Cfg.field.Aifsn = 2;
1642                RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1643                Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
1644                Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
1645                Ac3Cfg.field.Aifsn = 2;
1646                RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1647
1648                /*======================================================== */
1649                /*      DMA Register has a copy too. */
1650                /*======================================================== */
1651                csr0.field.Ac0Txop = 0; /* QID_AC_BE */
1652                csr0.field.Ac1Txop = 0; /* QID_AC_BK */
1653                RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1654                if (pAd->CommonCfg.PhyMode == PHY_11B) {
1655                        csr1.field.Ac2Txop = 192;       /* AC_VI: 192*32us ~= 6ms */
1656                        csr1.field.Ac3Txop = 96;        /* AC_VO: 96*32us  ~= 3ms */
1657                } else {
1658                        csr1.field.Ac2Txop = 96;        /* AC_VI: 96*32us ~= 3ms */
1659                        csr1.field.Ac3Txop = 48;        /* AC_VO: 48*32us ~= 1.5ms */
1660                }
1661                RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1662
1663                CwminCsr.word = 0;
1664                CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
1665                CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
1666                CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
1667                CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
1668                RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1669
1670                CwmaxCsr.word = 0;
1671                CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
1672                CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
1673                CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
1674                CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
1675                RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1676
1677                RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
1678
1679                NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm));
1680        } else {
1681                OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1682                /*======================================================== */
1683                /*      MAC Register has a copy. */
1684                /*======================================================== */
1685                /* */
1686                /* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */
1687                /* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */
1688                /* */
1689                /*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */
1690
1691                Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
1692                Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE];
1693                Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
1694                Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE];       /*+1; */
1695
1696                Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1697                Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK];       /*+2; */
1698                Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
1699                Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];       /*+1; */
1700
1701                Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
1702                if (pAd->Antenna.field.TxPath == 1) {
1703                        Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
1704                        Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
1705                } else {
1706                        Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
1707                        Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
1708                }
1709                Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
1710#ifdef RTMP_MAC_USB
1711                Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
1712#endif /* RTMP_MAC_USB // */
1713
1714                {
1715                        /* Tuning for Wi-Fi WMM S06 */
1716                        if (pAd->CommonCfg.bWiFiTest &&
1717                            pEdcaParm->Aifsn[QID_AC_VI] == 10)
1718                                Ac2Cfg.field.Aifsn -= 1;
1719
1720                        /* Tuning for TGn Wi-Fi 5.2.32 */
1721                        /* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */
1722                        if (STA_TGN_WIFI_ON(pAd) &&
1723                            pEdcaParm->Aifsn[QID_AC_VI] == 10) {
1724                                Ac0Cfg.field.Aifsn = 3;
1725                                Ac2Cfg.field.AcTxop = 5;
1726                        }
1727#ifdef RT30xx
1728                        if (pAd->RfIcType == RFIC_3020
1729                            || pAd->RfIcType == RFIC_2020) {
1730                                /* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */
1731                                Ac2Cfg.field.Aifsn = 5;
1732                        }
1733#endif /* RT30xx // */
1734                }
1735
1736                Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
1737                Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
1738                Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
1739                Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
1740
1741/*#ifdef WIFI_TEST */
1742                if (pAd->CommonCfg.bWiFiTest) {
1743                        if (Ac3Cfg.field.AcTxop == 102) {
1744                                Ac0Cfg.field.AcTxop =
1745                                    pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->
1746                                    Txop[QID_AC_BE] : 10;
1747                                Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1;   /* AIFSN must >= 1 */
1748                                Ac1Cfg.field.AcTxop =
1749                                    pEdcaParm->Txop[QID_AC_BK];
1750                                Ac1Cfg.field.Aifsn =
1751                                    pEdcaParm->Aifsn[QID_AC_BK];
1752                                Ac2Cfg.field.AcTxop =
1753                                    pEdcaParm->Txop[QID_AC_VI];
1754                        }       /* End of if */
1755                }
1756/*#endif // WIFI_TEST // */
1757
1758                RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1759                RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1760                RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1761                RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1762
1763                /*======================================================== */
1764                /*      DMA Register has a copy too. */
1765                /*======================================================== */
1766                csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
1767                csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
1768                RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1769
1770                csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
1771                csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
1772                RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1773
1774                CwminCsr.word = 0;
1775                CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
1776                CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
1777                CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
1778                CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1;        /*for TGn wifi test */
1779                RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1780
1781                CwmaxCsr.word = 0;
1782                CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
1783                CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
1784                CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
1785                CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
1786                RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1787
1788                AifsnCsr.word = 0;
1789                AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn;     /*pEdcaParm->Aifsn[QID_AC_BE]; */
1790                AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn;     /*pEdcaParm->Aifsn[QID_AC_BK]; */
1791                AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn;     /*pEdcaParm->Aifsn[QID_AC_VI]; */
1792
1793                {
1794                        /* Tuning for Wi-Fi WMM S06 */
1795                        if (pAd->CommonCfg.bWiFiTest &&
1796                            pEdcaParm->Aifsn[QID_AC_VI] == 10)
1797                                AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
1798
1799                        /* Tuning for TGn Wi-Fi 5.2.32 */
1800                        /* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */
1801                        if (STA_TGN_WIFI_ON(pAd) &&
1802                            pEdcaParm->Aifsn[QID_AC_VI] == 10) {
1803                                AifsnCsr.field.Aifsn0 = 3;
1804                                AifsnCsr.field.Aifsn2 = 7;
1805                        }
1806
1807                        if (INFRA_ON(pAd))
1808                                CLIENT_STATUS_SET_FLAG(&pAd->MacTab.
1809                                                       Content[BSSID_WCID],
1810                                                       fCLIENT_STATUS_WMM_CAPABLE);
1811                }
1812
1813                {
1814                        AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; /*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */
1815#ifdef RT30xx
1816                        /* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */
1817                        if (pAd->RfIcType == RFIC_3020
1818                            || pAd->RfIcType == RFIC_2020) {
1819                                AifsnCsr.field.Aifsn2 = 0x2;    /*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */
1820                        }
1821#endif /* RT30xx // */
1822                }
1823                RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
1824
1825                NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm,
1826                               sizeof(struct rt_edca_parm));
1827                if (!ADHOC_ON(pAd)) {
1828                        DBGPRINT(RT_DEBUG_TRACE,
1829                                 ("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n",
1830                                  pEdcaParm->EdcaUpdateCount));
1831                        DBGPRINT(RT_DEBUG_TRACE,
1832                                 ("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
1833                                  pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0],
1834                                  pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5,
1835                                  pEdcaParm->bACM[0]));
1836                        DBGPRINT(RT_DEBUG_TRACE,
1837                                 ("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
1838                                  pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1],
1839                                  pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5,
1840                                  pEdcaParm->bACM[1]));
1841                        DBGPRINT(RT_DEBUG_TRACE,
1842                                 ("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
1843                                  pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2],
1844                                  pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5,
1845                                  pEdcaParm->bACM[2]));
1846                        DBGPRINT(RT_DEBUG_TRACE,
1847                                 ("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
1848                                  pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3],
1849                                  pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5,
1850                                  pEdcaParm->bACM[3]));
1851                }
1852        }
1853
1854}
1855
1856/*
1857        ==========================================================================
1858        Description:
1859
1860        IRQL = PASSIVE_LEVEL
1861        IRQL = DISPATCH_LEVEL
1862
1863        ==========================================================================
1864 */
1865void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime)
1866{
1867        unsigned long SlotTime;
1868        u32 RegValue = 0;
1869
1870        if (pAd->CommonCfg.Channel > 14)
1871                bUseShortSlotTime = TRUE;
1872
1873        if (bUseShortSlotTime
1874            && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1875                return;
1876        else if ((!bUseShortSlotTime)
1877                 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
1878                return;
1879
1880        if (bUseShortSlotTime)
1881                OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1882        else
1883                OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1884
1885        SlotTime = (bUseShortSlotTime) ? 9 : 20;
1886
1887        {
1888                /* force using short SLOT time for FAE to demo performance when TxBurst is ON */
1889                if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1890                     && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1891                    || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
1892                        && (pAd->CommonCfg.BACapability.field.Policy ==
1893                            BA_NOTUSE))
1894                    ) {
1895                        /* In this case, we will think it is doing Wi-Fi test */
1896                        /* And we will not set to short slot when bEnableTxBurst is TRUE. */
1897                } else if (pAd->CommonCfg.bEnableTxBurst) {
1898                        OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1899                        SlotTime = 9;
1900                }
1901        }
1902
1903        /* */
1904        /* For some reasons, always set it to short slot time. */
1905        /* */
1906        /* ToDo: Should consider capability with 11B */
1907        /* */
1908        {
1909                if (pAd->StaCfg.BssType == BSS_ADHOC) {
1910                        OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1911                        SlotTime = 20;
1912                }
1913        }
1914
1915        RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
1916        RegValue = RegValue & 0xFFFFFF00;
1917
1918        RegValue |= SlotTime;
1919
1920        RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
1921}
1922
1923/*
1924        ========================================================================
1925        Description:
1926                Add Shared key information into ASIC.
1927                Update shared key, TxMic and RxMic to Asic Shared key table
1928                Update its cipherAlg to Asic Shared key Mode.
1929
1930    Return:
1931        ========================================================================
1932*/
1933void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
1934                           u8 BssIndex,
1935                           u8 KeyIdx,
1936                           u8 CipherAlg,
1937                           u8 *pKey, u8 *pTxMic, u8 *pRxMic)
1938{
1939        unsigned long offset;           /*, csr0; */
1940        SHAREDKEY_MODE_STRUC csr1;
1941#ifdef RTMP_MAC_PCI
1942        int i;
1943#endif /* RTMP_MAC_PCI // */
1944
1945        DBGPRINT(RT_DEBUG_TRACE,
1946                 ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,
1947                  KeyIdx));
1948/*============================================================================================ */
1949
1950        DBGPRINT(RT_DEBUG_TRACE,
1951                 ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg],
1952                  BssIndex * 4 + KeyIdx));
1953        DBGPRINT_RAW(RT_DEBUG_TRACE,
1954                     ("         Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1955                      pKey[0], pKey[1], pKey[2], pKey[3], pKey[4],
1956                      pKey[5], pKey[6], pKey[7], pKey[8], pKey[9],
1957                      pKey[10], pKey[11], pKey[12], pKey[13], pKey[14],
1958                      pKey[15]));
1959        if (pRxMic) {
1960                DBGPRINT_RAW(RT_DEBUG_TRACE,
1961                             ("         Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1962                              pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
1963                              pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
1964        }
1965        if (pTxMic) {
1966                DBGPRINT_RAW(RT_DEBUG_TRACE,
1967                             ("         Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1968                              pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
1969                              pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
1970        }
1971/*============================================================================================ */
1972        /* */
1973        /* fill key material - key + TX MIC + RX MIC */
1974        /* */
1975#ifdef RTMP_MAC_PCI
1976        offset =
1977            SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
1978        for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) {
1979                RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
1980        }
1981
1982        offset += MAX_LEN_OF_SHARE_KEY;
1983        if (pTxMic) {
1984                for (i = 0; i < 8; i++) {
1985                        RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
1986                }
1987        }
1988
1989        offset += 8;
1990        if (pRxMic) {
1991                for (i = 0; i < 8; i++) {
1992                        RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
1993                }
1994        }
1995#endif /* RTMP_MAC_PCI // */
1996#ifdef RTMP_MAC_USB
1997        {
1998                offset =
1999                    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
2000                                             KeyIdx) * HW_KEY_ENTRY_SIZE;
2001                RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
2002
2003                offset += MAX_LEN_OF_SHARE_KEY;
2004                if (pTxMic) {
2005                        RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2006                }
2007
2008                offset += 8;
2009                if (pRxMic) {
2010                        RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2011                }
2012        }
2013#endif /* RTMP_MAC_USB // */
2014
2015        /* */
2016        /* Update cipher algorithm. WSTA always use BSS0 */
2017        /* */
2018        RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2019                       &csr1.word);
2020        DBGPRINT(RT_DEBUG_TRACE,
2021                 ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n",
2022                  BssIndex, KeyIdx, csr1.word));
2023        if ((BssIndex % 2) == 0) {
2024                if (KeyIdx == 0)
2025                        csr1.field.Bss0Key0CipherAlg = CipherAlg;
2026                else if (KeyIdx == 1)
2027                        csr1.field.Bss0Key1CipherAlg = CipherAlg;
2028                else if (KeyIdx == 2)
2029                        csr1.field.Bss0Key2CipherAlg = CipherAlg;
2030                else
2031                        csr1.field.Bss0Key3CipherAlg = CipherAlg;
2032        } else {
2033                if (KeyIdx == 0)
2034                        csr1.field.Bss1Key0CipherAlg = CipherAlg;
2035                else if (KeyIdx == 1)
2036                        csr1.field.Bss1Key1CipherAlg = CipherAlg;
2037                else if (KeyIdx == 2)
2038                        csr1.field.Bss1Key2CipherAlg = CipherAlg;
2039                else
2040                        csr1.field.Bss1Key3CipherAlg = CipherAlg;
2041        }
2042        DBGPRINT(RT_DEBUG_TRACE,
2043                 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
2044                  BssIndex, csr1.word));
2045        RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2046                        csr1.word);
2047
2048}
2049
2050/*      IRQL = DISPATCH_LEVEL */
2051void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
2052                              u8 BssIndex, u8 KeyIdx)
2053{
2054        /*unsigned long SecCsr0; */
2055        SHAREDKEY_MODE_STRUC csr1;
2056
2057        DBGPRINT(RT_DEBUG_TRACE,
2058                 ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx));
2059
2060        RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2061                       &csr1.word);
2062        if ((BssIndex % 2) == 0) {
2063                if (KeyIdx == 0)
2064                        csr1.field.Bss0Key0CipherAlg = 0;
2065                else if (KeyIdx == 1)
2066                        csr1.field.Bss0Key1CipherAlg = 0;
2067                else if (KeyIdx == 2)
2068                        csr1.field.Bss0Key2CipherAlg = 0;
2069                else
2070                        csr1.field.Bss0Key3CipherAlg = 0;
2071        } else {
2072                if (KeyIdx == 0)
2073                        csr1.field.Bss1Key0CipherAlg = 0;
2074                else if (KeyIdx == 1)
2075                        csr1.field.Bss1Key1CipherAlg = 0;
2076                else if (KeyIdx == 2)
2077                        csr1.field.Bss1Key2CipherAlg = 0;
2078                else
2079                        csr1.field.Bss1Key3CipherAlg = 0;
2080        }
2081        DBGPRINT(RT_DEBUG_TRACE,
2082                 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
2083                  BssIndex, csr1.word));
2084        RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2085                        csr1.word);
2086        ASSERT(BssIndex < 4);
2087        ASSERT(KeyIdx < 4);
2088
2089}
2090
2091void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
2092                             u16 WCID,
2093                             u8 BssIndex,
2094                             u8 CipherAlg,
2095                             IN BOOLEAN bUsePairewiseKeyTable)
2096{
2097        unsigned long WCIDAttri = 0, offset;
2098
2099        /* */
2100        /* Update WCID attribute. */
2101        /* Only TxKey could update WCID attribute. */
2102        /* */
2103        offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
2104        WCIDAttri =
2105            (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
2106        RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2107}
2108
2109void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
2110                         u16 WCID, unsigned long uIV, unsigned long uEIV)
2111{
2112        unsigned long offset;
2113
2114        offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2115
2116        RTMP_IO_WRITE32(pAd, offset, uIV);
2117        RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
2118}
2119
2120void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
2121                           u16 WCID, u8 *pAddr)
2122{
2123        unsigned long offset;
2124        unsigned long Addr;
2125
2126        offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
2127        Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24);
2128        RTMP_IO_WRITE32(pAd, offset, Addr);
2129        Addr = pAddr[4] + (pAddr[5] << 8);
2130        RTMP_IO_WRITE32(pAd, offset + 4, Addr);
2131}
2132
2133/*
2134    ========================================================================
2135
2136    Routine Description:
2137        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
2138
2139    Arguments:
2140        pAd                     Pointer to our adapter
2141        WCID                    WCID Entry number.
2142        BssIndex                BSSID index, station or none multiple BSSID support
2143                                this value should be 0.
2144        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
2145        pCipherKey              Pointer to Cipher Key.
2146        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
2147                                otherwise PairewiseKey table
2148        bTxKey                  This is the transmit key if enabled.
2149
2150    Return Value:
2151        None
2152
2153    Note:
2154        This routine will set the relative key stuff to Asic including WCID attribute,
2155        Cipher Key, Cipher algorithm and IV/EIV.
2156
2157        IV/EIV will be update if this CipherKey is the transmission key because
2158        ASIC will base on IV's KeyID value to select Cipher Key.
2159
2160        If bTxKey sets to FALSE, this is not the TX key, but it could be
2161        RX key
2162
2163        For AP mode bTxKey must be always set to TRUE.
2164    ========================================================================
2165*/
2166void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
2167                     u16 WCID,
2168                     u8 BssIndex,
2169                     u8 KeyIdx,
2170                     struct rt_cipher_key *pCipherKey,
2171                     IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey)
2172{
2173        unsigned long offset;
2174/*      unsigned long   WCIDAttri = 0; */
2175        u8 IV4 = 0;
2176        u8 *pKey = pCipherKey->Key;
2177/*      unsigned long           KeyLen = pCipherKey->KeyLen; */
2178        u8 *pTxMic = pCipherKey->TxMic;
2179        u8 *pRxMic = pCipherKey->RxMic;
2180        u8 *pTxtsc = pCipherKey->TxTsc;
2181        u8 CipherAlg = pCipherKey->CipherAlg;
2182        SHAREDKEY_MODE_STRUC csr1;
2183#ifdef RTMP_MAC_PCI
2184        u8 i;
2185#endif /* RTMP_MAC_PCI // */
2186
2187/*      ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */
2188
2189        DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
2190        /* */
2191        /* 1.) decide key table offset */
2192        /* */
2193        if (bUsePairewiseKeyTable)
2194                offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2195        else
2196                offset =
2197                    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
2198                                             KeyIdx) * HW_KEY_ENTRY_SIZE;
2199
2200        /* */
2201        /* 2.) Set Key to Asic */
2202        /* */
2203        /*for (i = 0; i < KeyLen; i++) */
2204#ifdef RTMP_MAC_PCI
2205        for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
2206                RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2207        }
2208        offset += MAX_LEN_OF_PEER_KEY;
2209
2210        /* */
2211        /* 3.) Set MIC key if available */
2212        /* */
2213        if (pTxMic) {
2214                for (i = 0; i < 8; i++) {
2215                        RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2216                }
2217        }
2218        offset += LEN_TKIP_TXMICK;
2219
2220        if (pRxMic) {
2221                for (i = 0; i < 8; i++) {
2222                        RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2223                }
2224        }
2225#endif /* RTMP_MAC_PCI // */
2226#ifdef RTMP_MAC_USB
2227        RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
2228        offset += MAX_LEN_OF_PEER_KEY;
2229
2230        /* */
2231        /* 3.) Set MIC key if available */
2232        /* */
2233        if (pTxMic) {
2234                RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2235        }
2236        offset += LEN_TKIP_TXMICK;
2237
2238        if (pRxMic) {
2239                RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2240        }
2241#endif /* RTMP_MAC_USB // */
2242
2243        /* */
2244        /* 4.) Modify IV/EIV if needs */
2245        /*     This will force Asic to use this key ID by setting IV. */
2246        /* */
2247        if (bTxKey) {
2248#ifdef RTMP_MAC_PCI
2249                offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2250                /* */
2251                /* Write IV */
2252                /* */
2253                RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
2254                RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
2255                RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
2256
2257                IV4 = (KeyIdx << 6);
2258                if ((CipherAlg == CIPHER_TKIP)
2259                    || (CipherAlg == CIPHER_TKIP_NO_MIC)
2260                    || (CipherAlg == CIPHER_AES))
2261                        IV4 |= 0x20;    /* turn on extension bit means EIV existence */
2262
2263                RTMP_IO_WRITE8(pAd, offset + 3, IV4);
2264
2265                /* */
2266                /* Write EIV */
2267                /* */
2268                offset += 4;
2269                for (i = 0; i < 4; i++) {
2270                        RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
2271                }
2272#endif /* RTMP_MAC_PCI // */
2273#ifdef RTMP_MAC_USB
2274                u32 tmpVal;
2275
2276                /* */
2277                /* Write IV */
2278                /* */
2279                IV4 = (KeyIdx << 6);
2280                if ((CipherAlg == CIPHER_TKIP)
2281                    || (CipherAlg == CIPHER_TKIP_NO_MIC)
2282                    || (CipherAlg == CIPHER_AES))
2283                        IV4 |= 0x20;    /* turn on extension bit means EIV existence */
2284
2285                tmpVal =
2286                    pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) +
2287                    (pTxtsc[0] << 16) + (IV4 << 24);
2288                RTMP_IO_WRITE32(pAd, offset, tmpVal);
2289
2290                /* */
2291                /* Write EIV */
2292                /* */
2293                offset += 4;
2294                RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]);
2295#endif /* RTMP_MAC_USB // */
2296
2297                AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg,
2298                                        bUsePairewiseKeyTable);
2299        }
2300
2301        if (!bUsePairewiseKeyTable) {
2302                /* */
2303                /* Only update the shared key security mode */
2304                /* */
2305                RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2306                               &csr1.word);
2307                if ((BssIndex % 2) == 0) {
2308                        if (KeyIdx == 0)
2309                                csr1.field.Bss0Key0CipherAlg = CipherAlg;
2310                        else if (KeyIdx == 1)
2311                                csr1.field.Bss0Key1CipherAlg = CipherAlg;
2312                        else if (KeyIdx == 2)
2313                                csr1.field.Bss0Key2CipherAlg = CipherAlg;
2314                        else
2315                                csr1.field.Bss0Key3CipherAlg = CipherAlg;
2316                } else {
2317                        if (KeyIdx == 0)
2318                                csr1.field.Bss1Key0CipherAlg = CipherAlg;
2319                        else if (KeyIdx == 1)
2320                                csr1.field.Bss1Key1CipherAlg = CipherAlg;
2321                        else if (KeyIdx == 2)
2322                                csr1.field.Bss1Key2CipherAlg = CipherAlg;
2323                        else
2324                                csr1.field.Bss1Key3CipherAlg = CipherAlg;
2325                }
2326                RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2327                                csr1.word);
2328        }
2329
2330        DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
2331}
2332
2333/*
2334        ========================================================================
2335        Description:
2336                Add Pair-wise key material into ASIC.
2337                Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
2338
2339    Return:
2340        ========================================================================
2341*/
2342void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
2343                             u8 *pAddr,
2344                             u8 WCID, struct rt_cipher_key *pCipherKey)
2345{
2346        int i;
2347        unsigned long offset;
2348        u8 *pKey = pCipherKey->Key;
2349        u8 *pTxMic = pCipherKey->TxMic;
2350        u8 *pRxMic = pCipherKey->RxMic;
2351#ifdef DBG
2352        u8 CipherAlg = pCipherKey->CipherAlg;
2353#endif /* DBG // */
2354
2355        /* EKEY */
2356        offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2357#ifdef RTMP_MAC_PCI
2358        for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
2359                RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2360        }
2361#endif /* RTMP_MAC_PCI // */
2362#ifdef RTMP_MAC_USB
2363        RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
2364#endif /* RTMP_MAC_USB // */
2365        for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) {
2366                u32 Value;
2367                RTMP_IO_READ32(pAd, offset + i, &Value);
2368        }
2369
2370        offset += MAX_LEN_OF_PEER_KEY;
2371
2372        /*  MIC KEY */
2373        if (pTxMic) {
2374#ifdef RTMP_MAC_PCI
2375                for (i = 0; i < 8; i++) {
2376                        RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2377                }
2378#endif /* RTMP_MAC_PCI // */
2379#ifdef RTMP_MAC_USB
2380                RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
2381#endif /* RTMP_MAC_USB // */
2382        }
2383        offset += 8;
2384        if (pRxMic) {
2385#ifdef RTMP_MAC_PCI
2386                for (i = 0; i < 8; i++) {
2387                        RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2388                }
2389#endif /* RTMP_MAC_PCI // */
2390#ifdef RTMP_MAC_USB
2391                RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
2392#endif /* RTMP_MAC_USB // */
2393        }
2394
2395        DBGPRINT(RT_DEBUG_TRACE,
2396                 ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID,
2397                  CipherName[CipherAlg]));
2398        DBGPRINT(RT_DEBUG_TRACE,
2399                 ("     Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2400                  pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5],
2401                  pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11],
2402                  pKey[12], pKey[13], pKey[14], pKey[15]));
2403        if (pRxMic) {
2404                DBGPRINT(RT_DEBUG_TRACE,
2405                         ("     Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2406                          pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
2407                          pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
2408        }
2409        if (pTxMic) {
2410                DBGPRINT(RT_DEBUG_TRACE,
2411                         ("     Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2412                          pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
2413                          pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
2414        }
2415}
2416
2417/*
2418        ========================================================================
2419        Description:
2420                Remove Pair-wise key material from ASIC.
2421
2422    Return:
2423        ========================================================================
2424*/
2425void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
2426                                u8 BssIdx, u8 Wcid)
2427{
2428        unsigned long WCIDAttri;
2429        u16 offset;
2430
2431        /* re-set the entry's WCID attribute as OPEN-NONE. */
2432        offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
2433        WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE;
2434        RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2435}
2436
2437BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
2438                             u8 Command,
2439                             u8 Token, u8 Arg0, u8 Arg1)
2440{
2441
2442        if (pAd->chipOps.sendCommandToMcu)
2443                pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
2444
2445        return TRUE;
2446}
2447
2448void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
2449{
2450#ifdef RT30xx
2451        /* RT3572 ATE need not to do this. */
2452        RT30xxSetRxAnt(pAd, Ant);
2453#endif /* RT30xx // */
2454}
2455
2456void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
2457{
2458        if (pAd->chipOps.AsicRfTurnOff) {
2459                pAd->chipOps.AsicRfTurnOff(pAd);
2460        } else {
2461                /* RF R2 bit 18 = 0 */
2462                u32 R1 = 0, R2 = 0, R3 = 0;
2463                u8 index;
2464                struct rt_rtmp_rf_regs *RFRegTable;
2465
2466                RFRegTable = RF2850RegTable;
2467
2468                switch (pAd->RfIcType) {
2469                case RFIC_2820:
2470                case RFIC_2850:
2471                case RFIC_2720:
2472                case RFIC_2750:
2473
2474                        for (index = 0; index < NUM_OF_2850_CHNL; index++) {
2475                                if (Channel == RFRegTable[index].Channel) {
2476                                        R1 = RFRegTable[index].R1 & 0xffffdfff;
2477                                        R2 = RFRegTable[index].R2 & 0xfffbffff;
2478                                        R3 = RFRegTable[index].R3 & 0xfff3ffff;
2479
2480                                        RTMP_RF_IO_WRITE32(pAd, R1);
2481                                        RTMP_RF_IO_WRITE32(pAd, R2);
2482
2483                                        /* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */
2484                                        /* Set RF R2 bit18=0, R3 bit[18:19]=0 */
2485                                        /*if (pAd->StaCfg.bRadio == FALSE) */
2486                                        if (1) {
2487                                                RTMP_RF_IO_WRITE32(pAd, R3);
2488
2489                                                DBGPRINT(RT_DEBUG_TRACE,
2490                                                         ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
2491                                                          Channel,
2492                                                          pAd->RfIcType, R2,
2493                                                          R3));
2494                                        } else
2495                                                DBGPRINT(RT_DEBUG_TRACE,
2496                                                         ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
2497                                                          Channel,
2498                                                          pAd->RfIcType, R2));
2499                                        break;
2500                                }
2501                        }
2502                        break;
2503
2504                default:
2505                        break;
2506                }
2507        }
2508}
2509
2510void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
2511{
2512        /* RF R2 bit 18 = 0 */
2513        u32 R1 = 0, R2 = 0, R3 = 0;
2514        u8 index;
2515        struct rt_rtmp_rf_regs *RFRegTable;
2516
2517#ifdef PCIE_PS_SUPPORT
2518        /* The RF programming sequence is difference between 3xxx and 2xxx */
2519        if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
2520                return;
2521        }
2522#endif /* PCIE_PS_SUPPORT // */
2523
2524        RFRegTable = RF2850RegTable;
2525
2526        switch (pAd->RfIcType) {
2527        case RFIC_2820:
2528        case RFIC_2850:
2529        case RFIC_2720:
2530        case RFIC_2750:
2531
2532                for (index = 0; index < NUM_OF_2850_CHNL; index++) {
2533                        if (Channel == RFRegTable[index].Channel) {
2534                                R3 = pAd->LatchRfRegs.R3;
2535                                R3 &= 0xfff3ffff;
2536                                R3 |= 0x00080000;
2537                                RTMP_RF_IO_WRITE32(pAd, R3);
2538
2539                                R1 = RFRegTable[index].R1;
2540                                RTMP_RF_IO_WRITE32(pAd, R1);
2541
2542                                R2 = RFRegTable[index].R2;
2543                                if (pAd->Antenna.field.TxPath == 1) {
2544                                        R2 |= 0x4000;   /* If TXpath is 1, bit 14 = 1; */
2545                                }
2546
2547                                if (pAd->Antenna.field.RxPath == 2) {
2548                                        R2 |= 0x40;     /* write 1 to off Rxpath. */
2549                                } else if (pAd->Antenna.field.RxPath == 1) {
2550                                        R2 |= 0x20040;  /* write 1 to off RxPath */
2551                                }
2552                                RTMP_RF_IO_WRITE32(pAd, R2);
2553
2554                                break;
2555                        }
2556                }
2557                break;
2558
2559        default:
2560                break;
2561        }
2562
2563        DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
2564                                  Channel, pAd->RfIcType, R2));
2565}
2566