linux/drivers/staging/rt2870/common/rtusb_io.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        rtusb_io.c
  29
  30        Abstract:
  31
  32        Revision History:
  33        Who                     When        What
  34        --------        ----------  ----------------------------------------------
  35        Name            Date        Modification logs
  36        Paul Lin    06-25-2004  created
  37*/
  38
  39#include "../rt_config.h"
  40
  41
  42/*
  43        ========================================================================
  44
  45        Routine Description: NIC initialization complete
  46
  47        Arguments:
  48
  49        Return Value:
  50
  51        IRQL =
  52
  53        Note:
  54
  55        ========================================================================
  56*/
  57
  58NTSTATUS        RTUSBFirmwareRun(
  59        IN      PRTMP_ADAPTER   pAd)
  60{
  61        NTSTATUS        Status;
  62
  63        Status = RTUSB_VendorRequest(
  64                pAd,
  65                USBD_TRANSFER_DIRECTION_OUT,
  66                DEVICE_VENDOR_REQUEST_OUT,
  67                0x01,
  68                0x8,
  69                0,
  70                NULL,
  71                0);
  72
  73        return Status;
  74}
  75
  76
  77
  78/*
  79        ========================================================================
  80
  81        Routine Description: Write Firmware to NIC.
  82
  83        Arguments:
  84
  85        Return Value:
  86
  87        IRQL =
  88
  89        Note:
  90
  91        ========================================================================
  92*/
  93NTSTATUS RTUSBFirmwareWrite(
  94        IN PRTMP_ADAPTER pAd,
  95        IN PUCHAR               pFwImage,
  96        IN ULONG                FwLen)
  97{
  98        UINT32          MacReg;
  99        NTSTATUS        Status;
 100//      ULONG           i;
 101        USHORT          writeLen;
 102
 103        Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
 104
 105
 106        writeLen = FwLen;
 107        RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
 108
 109        Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
 110        Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
 111        Status = RTUSBFirmwareRun(pAd);
 112
 113        RTMPusecDelay(10000);
 114        RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
 115        AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
 116
 117        return Status;
 118}
 119
 120
 121/*
 122        ========================================================================
 123
 124        Routine Description: Get current firmware operation mode (Return Value)
 125
 126        Arguments:
 127
 128        Return Value:
 129                0 or 1 = Downloaded by host driver
 130                others = Driver doesn't download firmware
 131
 132        IRQL =
 133
 134        Note:
 135
 136        ========================================================================
 137*/
 138NTSTATUS        RTUSBFirmwareOpmode(
 139        IN      PRTMP_ADAPTER   pAd,
 140        OUT     PUINT32                 pValue)
 141{
 142        NTSTATUS        Status;
 143
 144        Status = RTUSB_VendorRequest(
 145                pAd,
 146                (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
 147                DEVICE_VENDOR_REQUEST_IN,
 148                0x1,
 149                0x11,
 150                0,
 151                pValue,
 152                4);
 153        return Status;
 154}
 155NTSTATUS        RTUSBVenderReset(
 156        IN      PRTMP_ADAPTER   pAd)
 157{
 158        NTSTATUS        Status;
 159        DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
 160        Status = RTUSB_VendorRequest(
 161                pAd,
 162                USBD_TRANSFER_DIRECTION_OUT,
 163                DEVICE_VENDOR_REQUEST_OUT,
 164                0x01,
 165                0x1,
 166                0,
 167                NULL,
 168                0);
 169
 170        DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
 171        return Status;
 172}
 173/*
 174        ========================================================================
 175
 176        Routine Description: Read various length data from RT2573
 177
 178        Arguments:
 179
 180        Return Value:
 181
 182        IRQL =
 183
 184        Note:
 185
 186        ========================================================================
 187*/
 188NTSTATUS        RTUSBMultiRead(
 189        IN      PRTMP_ADAPTER   pAd,
 190        IN      USHORT                  Offset,
 191        OUT     PUCHAR                  pData,
 192        IN      USHORT                  length)
 193{
 194        NTSTATUS        Status;
 195
 196        Status = RTUSB_VendorRequest(
 197                pAd,
 198                (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
 199                DEVICE_VENDOR_REQUEST_IN,
 200                0x7,
 201                0,
 202                Offset,
 203                pData,
 204                length);
 205
 206        return Status;
 207}
 208
 209/*
 210        ========================================================================
 211
 212        Routine Description: Write various length data to RT2573
 213
 214        Arguments:
 215
 216        Return Value:
 217
 218        IRQL =
 219
 220        Note:
 221
 222        ========================================================================
 223*/
 224NTSTATUS        RTUSBMultiWrite_OneByte(
 225        IN      PRTMP_ADAPTER   pAd,
 226        IN      USHORT                  Offset,
 227        IN      PUCHAR                  pData)
 228{
 229        NTSTATUS        Status;
 230
 231        // TODO: In 2870, use this funciton carefully cause it's not stable.
 232        Status = RTUSB_VendorRequest(
 233                pAd,
 234                USBD_TRANSFER_DIRECTION_OUT,
 235                DEVICE_VENDOR_REQUEST_OUT,
 236                0x6,
 237                0,
 238                Offset,
 239                pData,
 240                1);
 241
 242        return Status;
 243}
 244
 245NTSTATUS        RTUSBMultiWrite(
 246        IN      PRTMP_ADAPTER   pAd,
 247        IN      USHORT                  Offset,
 248        IN      PUCHAR                  pData,
 249        IN      USHORT                  length)
 250{
 251        NTSTATUS        Status;
 252
 253
 254        USHORT          index = 0,Value;
 255        PUCHAR          pSrc = pData;
 256        USHORT          resude = 0;
 257
 258        resude = length % 2;
 259                length  += resude;
 260                do
 261                {
 262                        Value =(USHORT)( *pSrc  | (*(pSrc + 1) << 8));
 263                Status = RTUSBSingleWrite(pAd,Offset + index,Value);
 264            index +=2;
 265            length -= 2;
 266            pSrc = pSrc + 2;
 267        }while(length > 0);
 268
 269        return Status;
 270}
 271
 272
 273NTSTATUS RTUSBSingleWrite(
 274        IN      RTMP_ADAPTER    *pAd,
 275        IN      USHORT                  Offset,
 276        IN      USHORT                  Value)
 277{
 278        NTSTATUS        Status;
 279
 280        Status = RTUSB_VendorRequest(
 281                pAd,
 282                USBD_TRANSFER_DIRECTION_OUT,
 283                DEVICE_VENDOR_REQUEST_OUT,
 284                0x2,
 285                Value,
 286                Offset,
 287                NULL,
 288                0);
 289
 290        return Status;
 291
 292}
 293
 294
 295/*
 296        ========================================================================
 297
 298        Routine Description: Read 32-bit MAC register
 299
 300        Arguments:
 301
 302        Return Value:
 303
 304        IRQL =
 305
 306        Note:
 307
 308        ========================================================================
 309*/
 310NTSTATUS        RTUSBReadMACRegister(
 311        IN      PRTMP_ADAPTER   pAd,
 312        IN      USHORT                  Offset,
 313        OUT     PUINT32                 pValue)
 314{
 315        NTSTATUS        Status;
 316        UINT32          localVal;
 317
 318        Status = RTUSB_VendorRequest(
 319                pAd,
 320                (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
 321                DEVICE_VENDOR_REQUEST_IN,
 322                0x7,
 323                0,
 324                Offset,
 325                &localVal,
 326                4);
 327
 328        *pValue = le2cpu32(localVal);
 329
 330
 331        if (Status < 0)
 332                *pValue = 0xffffffff;
 333
 334        return Status;
 335}
 336
 337
 338/*
 339        ========================================================================
 340
 341        Routine Description: Write 32-bit MAC register
 342
 343        Arguments:
 344
 345        Return Value:
 346
 347        IRQL =
 348
 349        Note:
 350
 351        ========================================================================
 352*/
 353NTSTATUS        RTUSBWriteMACRegister(
 354        IN      PRTMP_ADAPTER   pAd,
 355        IN      USHORT                  Offset,
 356        IN      UINT32                  Value)
 357{
 358        NTSTATUS        Status;
 359        UINT32          localVal;
 360
 361        localVal = Value;
 362
 363        Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
 364        Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
 365
 366        return Status;
 367}
 368
 369
 370
 371#if 1
 372/*
 373        ========================================================================
 374
 375        Routine Description: Read 8-bit BBP register
 376
 377        Arguments:
 378
 379        Return Value:
 380
 381        IRQL =
 382
 383        Note:
 384
 385        ========================================================================
 386*/
 387NTSTATUS        RTUSBReadBBPRegister(
 388        IN      PRTMP_ADAPTER   pAd,
 389        IN      UCHAR                   Id,
 390        IN      PUCHAR                  pValue)
 391{
 392        BBP_CSR_CFG_STRUC       BbpCsr;
 393        UINT                    i = 0;
 394        NTSTATUS                status;
 395
 396        // Verify the busy condition
 397        do
 398        {
 399                status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
 400                if(status >= 0)
 401                {
 402                if (!(BbpCsr.field.Busy == BUSY))
 403                        break;
 404                }
 405                printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
 406                i++;
 407        }
 408        while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 409
 410        if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
 411        {
 412                //
 413                // Read failed then Return Default value.
 414                //
 415                *pValue = pAd->BbpWriteLatch[Id];
 416
 417                DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
 418                return STATUS_UNSUCCESSFUL;
 419        }
 420
 421        // Prepare for write material
 422        BbpCsr.word                             = 0;
 423        BbpCsr.field.fRead                      = 1;
 424        BbpCsr.field.Busy                       = 1;
 425        BbpCsr.field.RegNum             = Id;
 426        RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
 427
 428        i = 0;
 429        // Verify the busy condition
 430        do
 431        {
 432                status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
 433                if (status >= 0)
 434                {
 435                if (!(BbpCsr.field.Busy == BUSY))
 436                {
 437                        *pValue = (UCHAR)BbpCsr.field.Value;
 438                        break;
 439                }
 440                }
 441                printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
 442                i++;
 443        }
 444        while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 445
 446        if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
 447        {
 448                //
 449                // Read failed then Return Default value.
 450                //
 451                *pValue = pAd->BbpWriteLatch[Id];
 452
 453                DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
 454                return STATUS_UNSUCCESSFUL;
 455        }
 456
 457        return STATUS_SUCCESS;
 458}
 459#else
 460/*
 461        ========================================================================
 462
 463        Routine Description: Read 8-bit BBP register via firmware
 464
 465        Arguments:
 466
 467        Return Value:
 468
 469        IRQL =
 470
 471        Note:
 472
 473        ========================================================================
 474*/
 475NTSTATUS        RTUSBReadBBPRegister(
 476        IN      PRTMP_ADAPTER   pAd,
 477        IN      UCHAR                   Id,
 478        IN      PUCHAR                  pValue)
 479{
 480        BBP_CSR_CFG_STRUC       BbpCsr;
 481        int                                     i, k;
 482        for (i=0; i<MAX_BUSY_COUNT; i++)
 483        {
 484                RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
 485                if (BbpCsr.field.Busy == BUSY)
 486                {
 487                        continue;
 488                }
 489                BbpCsr.word = 0;
 490                BbpCsr.field.fRead = 1;
 491                BbpCsr.field.BBP_RW_MODE = 1;
 492                BbpCsr.field.Busy = 1;
 493                BbpCsr.field.RegNum = Id;
 494                RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
 495                AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
 496                for (k=0; k<MAX_BUSY_COUNT; k++)
 497                {
 498                        RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
 499                        if (BbpCsr.field.Busy == IDLE)
 500                                break;
 501                }
 502                if ((BbpCsr.field.Busy == IDLE) &&
 503                        (BbpCsr.field.RegNum == Id))
 504                {
 505                        *pValue = (UCHAR)BbpCsr.field.Value;
 506                        break;
 507                }
 508        }
 509        if (BbpCsr.field.Busy == BUSY)
 510        {
 511                DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
 512                *pValue = pAd->BbpWriteLatch[Id];
 513                return STATUS_UNSUCCESSFUL;
 514        }
 515        return STATUS_SUCCESS;
 516}
 517#endif
 518
 519#if 1
 520/*
 521        ========================================================================
 522
 523        Routine Description: Write 8-bit BBP register
 524
 525        Arguments:
 526
 527        Return Value:
 528
 529        IRQL =
 530
 531        Note:
 532
 533        ========================================================================
 534*/
 535NTSTATUS        RTUSBWriteBBPRegister(
 536        IN      PRTMP_ADAPTER   pAd,
 537        IN      UCHAR                   Id,
 538        IN      UCHAR                   Value)
 539{
 540        BBP_CSR_CFG_STRUC       BbpCsr;
 541        UINT                    i = 0;
 542        NTSTATUS                status;
 543        // Verify the busy condition
 544        do
 545        {
 546                status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
 547                if (status >= 0)
 548                {
 549                if (!(BbpCsr.field.Busy == BUSY))
 550                        break;
 551                }
 552                printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
 553                i++;
 554        }
 555        while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 556
 557        if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
 558        {
 559                DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
 560                return STATUS_UNSUCCESSFUL;
 561        }
 562
 563        // Prepare for write material
 564        BbpCsr.word                             = 0;
 565        BbpCsr.field.fRead                      = 0;
 566        BbpCsr.field.Value                      = Value;
 567        BbpCsr.field.Busy                       = 1;
 568        BbpCsr.field.RegNum             = Id;
 569        RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
 570
 571        pAd->BbpWriteLatch[Id] = Value;
 572
 573        return STATUS_SUCCESS;
 574}
 575#else
 576/*
 577        ========================================================================
 578
 579        Routine Description: Write 8-bit BBP register via firmware
 580
 581        Arguments:
 582
 583        Return Value:
 584
 585        IRQL =
 586
 587        Note:
 588
 589        ========================================================================
 590*/
 591
 592NTSTATUS        RTUSBWriteBBPRegister(
 593        IN      PRTMP_ADAPTER   pAd,
 594        IN      UCHAR                   Id,
 595        IN      UCHAR                   Value)
 596
 597{
 598        BBP_CSR_CFG_STRUC       BbpCsr;
 599        int                                     BusyCnt;
 600        for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
 601        {
 602                RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
 603                if (BbpCsr.field.Busy == BUSY)
 604                        continue;
 605                BbpCsr.word = 0;
 606                BbpCsr.field.fRead = 0;
 607                BbpCsr.field.BBP_RW_MODE = 1;
 608                BbpCsr.field.Busy = 1;
 609                BbpCsr.field.Value = Value;
 610                BbpCsr.field.RegNum = Id;
 611                RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
 612                AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
 613                pAd->BbpWriteLatch[Id] = Value;
 614                break;
 615        }
 616        if (BusyCnt == MAX_BUSY_COUNT)
 617        {
 618                DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
 619                return STATUS_UNSUCCESSFUL;
 620        }
 621        return STATUS_SUCCESS;
 622}
 623#endif
 624/*
 625        ========================================================================
 626
 627        Routine Description: Write RF register through MAC
 628
 629        Arguments:
 630
 631        Return Value:
 632
 633        IRQL =
 634
 635        Note:
 636
 637        ========================================================================
 638*/
 639NTSTATUS        RTUSBWriteRFRegister(
 640        IN      PRTMP_ADAPTER   pAd,
 641        IN      UINT32                  Value)
 642{
 643        PHY_CSR4_STRUC  PhyCsr4;
 644        UINT                    i = 0;
 645        NTSTATUS                status;
 646
 647        NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
 648        do
 649        {
 650                status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
 651                if (status >= 0)
 652                {
 653                if (!(PhyCsr4.field.Busy))
 654                        break;
 655                }
 656                printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
 657                i++;
 658        }
 659        while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 660
 661        if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
 662        {
 663                DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
 664                return STATUS_UNSUCCESSFUL;
 665        }
 666
 667        RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
 668
 669        return STATUS_SUCCESS;
 670}
 671
 672/*
 673        ========================================================================
 674
 675        Routine Description: Write RT30xx RF register through MAC
 676
 677        Arguments:
 678
 679        Return Value:
 680
 681        IRQL =
 682
 683        Note:
 684
 685        ========================================================================
 686*/
 687NTSTATUS RT30xxWriteRFRegister(
 688        IN      PRTMP_ADAPTER   pAd,
 689        IN      UCHAR                   RegID,
 690        IN      UCHAR                   Value)
 691{
 692        RF_CSR_CFG_STRUC        rfcsr;
 693        UINT                            i = 0;
 694
 695        do
 696        {
 697                RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
 698
 699                if (!rfcsr.field.RF_CSR_KICK)
 700                        break;
 701                i++;
 702        }
 703        while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
 704
 705        if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
 706        {
 707                DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
 708                return STATUS_UNSUCCESSFUL;
 709        }
 710
 711        rfcsr.field.RF_CSR_WR = 1;
 712        rfcsr.field.RF_CSR_KICK = 1;
 713        rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
 714        rfcsr.field.RF_CSR_DATA = Value;
 715
 716        RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
 717
 718        return STATUS_SUCCESS;
 719}
 720
 721
 722/*
 723        ========================================================================
 724
 725        Routine Description: Read RT30xx RF register through MAC
 726
 727        Arguments:
 728
 729        Return Value:
 730
 731        IRQL =
 732
 733        Note:
 734
 735        ========================================================================
 736*/
 737NTSTATUS RT30xxReadRFRegister(
 738        IN      PRTMP_ADAPTER   pAd,
 739        IN      UCHAR                   RegID,
 740        IN      PUCHAR                  pValue)
 741{
 742        RF_CSR_CFG_STRUC        rfcsr;
 743        UINT                            i=0, k=0;
 744
 745        for (i=0; i<MAX_BUSY_COUNT; i++)
 746        {
 747                RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
 748
 749                if (rfcsr.field.RF_CSR_KICK == BUSY)
 750                {
 751                        continue;
 752                }
 753                rfcsr.word = 0;
 754                rfcsr.field.RF_CSR_WR = 0;
 755                rfcsr.field.RF_CSR_KICK = 1;
 756                rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
 757                RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
 758                for (k=0; k<MAX_BUSY_COUNT; k++)
 759                {
 760                        RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
 761
 762                        if (rfcsr.field.RF_CSR_KICK == IDLE)
 763                                break;
 764                }
 765                if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
 766                        (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
 767                {
 768                        *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
 769                        break;
 770                }
 771        }
 772        if (rfcsr.field.RF_CSR_KICK == BUSY)
 773        {
 774                DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
 775                return STATUS_UNSUCCESSFUL;
 776        }
 777
 778        return STATUS_SUCCESS;
 779}
 780
 781/*
 782        ========================================================================
 783
 784        Routine Description:
 785
 786        Arguments:
 787
 788        Return Value:
 789
 790        IRQL =
 791
 792        Note:
 793
 794        ========================================================================
 795*/
 796NTSTATUS        RTUSBReadEEPROM(
 797        IN      PRTMP_ADAPTER   pAd,
 798        IN      USHORT                  Offset,
 799        OUT     PUCHAR                  pData,
 800        IN      USHORT                  length)
 801{
 802        NTSTATUS        Status = STATUS_SUCCESS;
 803
 804        if(pAd->bUseEfuse)
 805                Status =eFuseRead(pAd, Offset, pData, length);
 806        else
 807        {
 808        Status = RTUSB_VendorRequest(
 809                pAd,
 810                (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
 811                DEVICE_VENDOR_REQUEST_IN,
 812                0x9,
 813                0,
 814                Offset,
 815                pData,
 816                length);
 817        }
 818
 819        return Status;
 820}
 821
 822/*
 823        ========================================================================
 824
 825        Routine Description:
 826
 827        Arguments:
 828
 829        Return Value:
 830
 831        IRQL =
 832
 833        Note:
 834
 835        ========================================================================
 836*/
 837NTSTATUS        RTUSBWriteEEPROM(
 838        IN      PRTMP_ADAPTER   pAd,
 839        IN      USHORT                  Offset,
 840        IN      PUCHAR                  pData,
 841        IN      USHORT                  length)
 842{
 843        NTSTATUS        Status = STATUS_SUCCESS;
 844
 845        if(pAd->bUseEfuse)
 846                Status = eFuseWrite(pAd, Offset, pData, length);
 847        else
 848        {
 849        Status = RTUSB_VendorRequest(
 850                pAd,
 851                USBD_TRANSFER_DIRECTION_OUT,
 852                DEVICE_VENDOR_REQUEST_OUT,
 853                0x8,
 854                0,
 855                Offset,
 856                pData,
 857                length);
 858        }
 859
 860        return Status;
 861}
 862
 863/*
 864        ========================================================================
 865
 866        Routine Description:
 867
 868        Arguments:
 869
 870        Return Value:
 871
 872        IRQL =
 873
 874        Note:
 875
 876        ========================================================================
 877*/
 878VOID RTUSBPutToSleep(
 879        IN      PRTMP_ADAPTER   pAd)
 880{
 881        UINT32          value;
 882
 883        // Timeout 0x40 x 50us
 884        value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
 885        RTUSBWriteMACRegister(pAd, 0x7010, value);
 886        RTUSBWriteMACRegister(pAd, 0x404, 0x30);
 887        //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 888        DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
 889
 890}
 891
 892/*
 893        ========================================================================
 894
 895        Routine Description:
 896
 897        Arguments:
 898
 899        Return Value:
 900
 901        IRQL =
 902
 903        Note:
 904
 905        ========================================================================
 906*/
 907NTSTATUS RTUSBWakeUp(
 908        IN      PRTMP_ADAPTER   pAd)
 909{
 910        NTSTATUS        Status;
 911
 912        Status = RTUSB_VendorRequest(
 913                pAd,
 914                USBD_TRANSFER_DIRECTION_OUT,
 915                DEVICE_VENDOR_REQUEST_OUT,
 916                0x01,
 917                0x09,
 918                0,
 919                NULL,
 920                0);
 921
 922        return Status;
 923}
 924
 925/*
 926        ========================================================================
 927
 928        Routine Description:
 929
 930        Arguments:
 931
 932        Return Value:
 933
 934        IRQL =
 935
 936        Note:
 937
 938        ========================================================================
 939*/
 940VOID    RTUSBInitializeCmdQ(
 941        IN      PCmdQ   cmdq)
 942{
 943        cmdq->head = NULL;
 944        cmdq->tail = NULL;
 945        cmdq->size = 0;
 946        cmdq->CmdQState = RT2870_THREAD_INITED;
 947}
 948
 949/*
 950        ========================================================================
 951
 952        Routine Description:
 953
 954        Arguments:
 955
 956        Return Value:
 957
 958        IRQL =
 959
 960        Note:
 961
 962        ========================================================================
 963*/
 964NDIS_STATUS     RTUSBEnqueueCmdFromNdis(
 965        IN      PRTMP_ADAPTER   pAd,
 966        IN      NDIS_OID                Oid,
 967        IN      BOOLEAN                 SetInformation,
 968        IN      PVOID                   pInformationBuffer,
 969        IN      UINT32                  InformationBufferLength)
 970{
 971        NDIS_STATUS     status;
 972        PCmdQElmt       cmdqelmt = NULL;
 973        POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
 974
 975        if (pid_nr(pObj->RTUSBCmdThr_pid) > 0)
 976                return (NDIS_STATUS_RESOURCES);
 977
 978        status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
 979        if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
 980                return (NDIS_STATUS_RESOURCES);
 981
 982                cmdqelmt->buffer = NULL;
 983                if (pInformationBuffer != NULL)
 984                {
 985                        status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
 986                        if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
 987                        {
 988                                kfree(cmdqelmt);
 989                                return (NDIS_STATUS_RESOURCES);
 990                        }
 991                        else
 992                        {
 993                                NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
 994                                cmdqelmt->bufferlength = InformationBufferLength;
 995                        }
 996                }
 997                else
 998                        cmdqelmt->bufferlength = 0;
 999
1000        cmdqelmt->command = Oid;
1001        cmdqelmt->CmdFromNdis = TRUE;
1002        if (SetInformation == TRUE)
1003                cmdqelmt->SetOperation = TRUE;
1004        else
1005                cmdqelmt->SetOperation = FALSE;
1006
1007        NdisAcquireSpinLock(&pAd->CmdQLock);
1008        if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
1009        {
1010                EnqueueCmd((&pAd->CmdQ), cmdqelmt);
1011                status = NDIS_STATUS_SUCCESS;
1012        }
1013        else
1014        {
1015                status = NDIS_STATUS_FAILURE;
1016        }
1017        NdisReleaseSpinLock(&pAd->CmdQLock);
1018
1019        if (status == NDIS_STATUS_FAILURE)
1020        {
1021                if (cmdqelmt->buffer)
1022                        NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1023                NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1024        }
1025        else
1026        RTUSBCMDUp(pAd);
1027
1028
1029    return(NDIS_STATUS_SUCCESS);
1030}
1031
1032/*
1033        ========================================================================
1034
1035        Routine Description:
1036
1037        Arguments:
1038
1039        Return Value:
1040
1041        IRQL =
1042
1043        Note:
1044
1045        ========================================================================
1046*/
1047NDIS_STATUS RTUSBEnqueueInternalCmd(
1048        IN PRTMP_ADAPTER        pAd,
1049        IN NDIS_OID                     Oid,
1050        IN PVOID                        pInformationBuffer,
1051        IN UINT32                       InformationBufferLength)
1052{
1053        NDIS_STATUS     status;
1054        PCmdQElmt       cmdqelmt = NULL;
1055
1056
1057        status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
1058        if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
1059                return (NDIS_STATUS_RESOURCES);
1060        NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
1061
1062        if(InformationBufferLength > 0)
1063        {
1064                status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
1065                if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
1066                {
1067                        NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1068                        return (NDIS_STATUS_RESOURCES);
1069                }
1070                else
1071                {
1072                        NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
1073                        cmdqelmt->bufferlength = InformationBufferLength;
1074                }
1075        }
1076        else
1077        {
1078                cmdqelmt->buffer = NULL;
1079                cmdqelmt->bufferlength = 0;
1080        }
1081
1082        cmdqelmt->command = Oid;
1083        cmdqelmt->CmdFromNdis = FALSE;
1084
1085        if (cmdqelmt != NULL)
1086        {
1087                NdisAcquireSpinLock(&pAd->CmdQLock);
1088                if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
1089                {
1090                        EnqueueCmd((&pAd->CmdQ), cmdqelmt);
1091                        status = NDIS_STATUS_SUCCESS;
1092                }
1093                else
1094                {
1095                        status = NDIS_STATUS_FAILURE;
1096                }
1097                NdisReleaseSpinLock(&pAd->CmdQLock);
1098
1099                if (status == NDIS_STATUS_FAILURE)
1100                {
1101                        if (cmdqelmt->buffer)
1102                                NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1103                        NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1104                }
1105                else
1106                RTUSBCMDUp(pAd);
1107        }
1108        return(NDIS_STATUS_SUCCESS);
1109}
1110
1111/*
1112        ========================================================================
1113
1114        Routine Description:
1115
1116        Arguments:
1117
1118        Return Value:
1119
1120        IRQL =
1121
1122        Note:
1123
1124        ========================================================================
1125*/
1126VOID    RTUSBDequeueCmd(
1127        IN      PCmdQ           cmdq,
1128        OUT     PCmdQElmt       *pcmdqelmt)
1129{
1130        *pcmdqelmt = cmdq->head;
1131
1132        if (*pcmdqelmt != NULL)
1133        {
1134                cmdq->head = cmdq->head->next;
1135                cmdq->size--;
1136                if (cmdq->size == 0)
1137                        cmdq->tail = NULL;
1138        }
1139}
1140
1141/*
1142    ========================================================================
1143          usb_control_msg - Builds a control urb, sends it off and waits for completion
1144          @dev: pointer to the usb device to send the message to
1145          @pipe: endpoint "pipe" to send the message to
1146          @request: USB message request value
1147          @requesttype: USB message request type value
1148          @value: USB message value
1149          @index: USB message index value
1150          @data: pointer to the data to send
1151          @size: length in bytes of the data to send
1152          @timeout: time in jiffies to wait for the message to complete before
1153                          timing out (if 0 the wait is forever)
1154          Context: !in_interrupt ()
1155
1156          This function sends a simple control message to a specified endpoint
1157          and waits for the message to complete, or timeout.
1158          If successful, it returns the number of bytes transferred, otherwise a negative error number.
1159
1160         Don't use this function from within an interrupt context, like a
1161          bottom half handler.  If you need an asynchronous message, or need to send
1162          a message from within interrupt context, use usb_submit_urb()
1163          If a thread in your driver uses this call, make sure your disconnect()
1164          method can wait for it to complete.  Since you don't have a handle on
1165          the URB used, you can't cancel the request.
1166
1167
1168        Routine Description:
1169
1170        Arguments:
1171
1172        Return Value:
1173
1174        Note:
1175
1176        ========================================================================
1177*/
1178NTSTATUS    RTUSB_VendorRequest(
1179        IN      PRTMP_ADAPTER   pAd,
1180        IN      UINT32                  TransferFlags,
1181        IN      UCHAR                   RequestType,
1182        IN      UCHAR                   Request,
1183        IN      USHORT                  Value,
1184        IN      USHORT                  Index,
1185        IN      PVOID                   TransferBuffer,
1186        IN      UINT32                  TransferBufferLength)
1187{
1188        int                             ret;
1189        POS_COOKIE              pObj = (POS_COOKIE) pAd->OS_Cookie;
1190
1191        if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1192        {
1193                DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
1194                return -1;
1195        }
1196        else if (in_interrupt())
1197        {
1198                DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
1199
1200                return -1;
1201        }
1202        else
1203        {
1204#define MAX_RETRY_COUNT  10
1205
1206                int retryCount = 0;
1207                void    *tmpBuf = TransferBuffer;
1208
1209                // Acquire Control token
1210                do {
1211                if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1212                        ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1213                else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1214                        ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1215                else
1216                {
1217                        DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
1218                        ret = -1;
1219                }
1220
1221                        retryCount++;
1222                        if (ret < 0) {
1223                                printk("#\n");
1224                                RTMPusecDelay(5000);
1225                        }
1226                } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
1227
1228        if (ret < 0) {
1229//                      DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
1230                        DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
1231                                                ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
1232                        if (Request == 0x2)
1233                                DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
1234
1235                        if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
1236                                hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
1237        }
1238        }
1239        return ret;
1240}
1241
1242/*
1243        ========================================================================
1244
1245        Routine Description:
1246          Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
1247          synchronously. Callers of this function must be running at
1248          PASSIVE LEVEL.
1249
1250        Arguments:
1251
1252        Return Value:
1253
1254        Note:
1255
1256        ========================================================================
1257*/
1258NTSTATUS        RTUSB_ResetDevice(
1259        IN      PRTMP_ADAPTER   pAd)
1260{
1261        NTSTATUS                Status = TRUE;
1262
1263        DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
1264        //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
1265        return Status;
1266}
1267
1268VOID CMDHandler(
1269    IN PRTMP_ADAPTER pAd)
1270{
1271        PCmdQElmt               cmdqelmt;
1272        PUCHAR                  pData;
1273        NDIS_STATUS             NdisStatus = NDIS_STATUS_SUCCESS;
1274//      ULONG                   Now = 0;
1275        NTSTATUS                ntStatus;
1276//      unsigned long   IrqFlags;
1277
1278        while (pAd->CmdQ.size > 0)
1279        {
1280                NdisStatus = NDIS_STATUS_SUCCESS;
1281
1282                NdisAcquireSpinLock(&pAd->CmdQLock);
1283                RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
1284                NdisReleaseSpinLock(&pAd->CmdQLock);
1285
1286                if (cmdqelmt == NULL)
1287                        break;
1288
1289                pData = cmdqelmt->buffer;
1290
1291                if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1292                {
1293                        switch (cmdqelmt->command)
1294                        {
1295                                case CMDTHREAD_CHECK_GPIO:
1296                                        {
1297                                                UINT32 data;
1298
1299                                                {
1300                                                        // Read GPIO pin2 as Hardware controlled radio state
1301
1302                                                        RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
1303
1304                                                        if (data & 0x04)
1305                                                        {
1306                                                                pAd->StaCfg.bHwRadio = TRUE;
1307                                                        }
1308                                                        else
1309                                                        {
1310                                                                pAd->StaCfg.bHwRadio = FALSE;
1311                                                        }
1312
1313                                                        if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1314                                                        {
1315                                                                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1316                                                                if(pAd->StaCfg.bRadio == TRUE)
1317                                                                {
1318                                                                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
1319
1320                                                                        MlmeRadioOn(pAd);
1321                                                                        // Update extra information
1322                                                                        pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1323                                                                }
1324                                                                else
1325                                                                {
1326                                                                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
1327
1328                                                                        MlmeRadioOff(pAd);
1329                                                                        // Update extra information
1330                                                                        pAd->ExtraInfo = HW_RADIO_OFF;
1331                                                                }
1332                                                        }
1333                                                }
1334                                        }
1335                                        break;
1336
1337                                case CMDTHREAD_QKERIODIC_EXECUT:
1338                                        {
1339                                                StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
1340                                        }
1341                                        break;
1342
1343                                case CMDTHREAD_RESET_BULK_OUT:
1344                                        {
1345                                                UINT32          MACValue;
1346                                                UCHAR           Index;
1347                                                int                     ret=0;
1348                                                PHT_TX_CONTEXT  pHTTXContext;
1349//                                              RTMP_TX_RING *pTxRing;
1350                                                unsigned long IrqFlags;
1351
1352                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
1353                                                // All transfers must be aborted or cancelled before attempting to reset the pipe.
1354                                                //RTUSBCancelPendingBulkOutIRP(pAd);
1355                                                // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
1356                                                Index = 0;
1357                                                do
1358                                                {
1359                                                        RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
1360                                                        if ((MACValue & 0xf00000/*0x800000*/) == 0)
1361                                                                break;
1362                                                        Index++;
1363                                                        RTMPusecDelay(10000);
1364                                                }while(Index < 100);
1365                                                MACValue = 0;
1366                                                RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1367                                                // To prevent Read Register error, we 2nd check the validity.
1368                                                if ((MACValue & 0xc00000) == 0)
1369                                                        RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1370                                                // To prevent Read Register error, we 3rd check the validity.
1371                                                if ((MACValue & 0xc00000) == 0)
1372                                                        RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1373                                                MACValue |= 0x80000;
1374                                                RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1375
1376                                                // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1377                                                RTMPusecDelay(1000);
1378
1379                                                MACValue &= (~0x80000);
1380                                                RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1381                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
1382
1383                                                // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1384                                                //RTMPusecDelay(5000);
1385
1386                                                if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
1387                                                {
1388                                                        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1389                                                        if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1390                                                        {
1391                                                                RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1392                                                        }
1393                                                        RTUSBKickBulkOut(pAd);
1394
1395                                                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
1396                                                }
1397                                                else
1398                                                {
1399                                                        pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
1400                                                        //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1401                                                        RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1402                                                        if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
1403                                                        {
1404                                                                pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
1405                                                                pHTTXContext->IRPPending = TRUE;
1406                                                                pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
1407
1408                                                                // no matter what, clean the flag
1409                                                                RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1410
1411                                                                //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1412                                                                RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1413/*-----------------------------------------------------------------------------------------------*/
1414/*-----------------------------------------------------------------------------------------------*/
1415                                                                {
1416                                                                RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
1417
1418                                                                if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
1419                                                                {
1420                                                                                RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1421                                                                        pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
1422                                                                        pHTTXContext->IRPPending = FALSE;
1423                                                                                pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
1424                                                                                RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1425
1426                                                                                DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
1427                                                                }
1428                                                                        else
1429                                                                        {
1430                                                                                RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1431                                                                                DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
1432                                                                                                pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
1433                                                                                                                        pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
1434                                                                                DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
1435                                                                                                                        pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1436                                                                                RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1437                                                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
1438
1439                                                                        }
1440                                                                }
1441                                                        }
1442                                                        else
1443                                                        {
1444                                                                //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1445                                                                //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1446
1447                                                                DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
1448                                                                if (pAd->bulkResetPipeid == 0)
1449                                                                {
1450                                                                        UCHAR   pendingContext = 0;
1451                                                                        PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
1452                                                                        PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
1453                                                                        PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
1454                                                                        PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
1455
1456                                                                        if (pHTTXContext->IRPPending)
1457                                                                                pendingContext |= 1;
1458                                                                        else if (pMLMEContext->IRPPending)
1459                                                                                pendingContext |= 2;
1460                                                                        else if (pNULLContext->IRPPending)
1461                                                                                pendingContext |= 4;
1462                                                                        else if (pPsPollContext->IRPPending)
1463                                                                                pendingContext |= 8;
1464                                                                        else
1465                                                                                pendingContext = 0;
1466
1467                                                                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
1468                                                                }
1469
1470                                                        // no matter what, clean the flag
1471                                                        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1472
1473                                                                RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1474
1475                                                                RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
1476                                                        }
1477
1478                                                        RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1479                                                        //RTUSBKickBulkOut(pAd);
1480                                                }
1481
1482                                        }
1483                                        /*
1484                                                // Don't cancel BULKIN.
1485                                                while ((atomic_read(&pAd->PendingRx) > 0) &&
1486                                                                (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1487                                                {
1488                                                        if (atomic_read(&pAd->PendingRx) > 0)
1489                                                        {
1490                                                                DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
1491                                                                RTUSBCancelPendingBulkInIRP(pAd);
1492                                                        }
1493                                                        RTMPusecDelay(100000);
1494                                                }
1495
1496                                                if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1497                                                {
1498                                                        UCHAR   i;
1499                                                        RTUSBRxPacket(pAd);
1500                                                        pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1501                                                        pAd->NextRxBulkInIndex          = 0;    // Rx Bulk pointer
1502                                                        for (i = 0; i < (RX_RING_SIZE); i++)
1503                                                        {
1504                                                                PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
1505
1506                                                                pRxContext->pAd = pAd;
1507                                                                pRxContext->InUse               = FALSE;
1508                                                                pRxContext->IRPPending  = FALSE;
1509                                                                pRxContext->Readable    = FALSE;
1510                                                                pRxContext->ReorderInUse = FALSE;
1511
1512                                                        }
1513                                                        RTUSBBulkReceive(pAd);
1514                                                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
1515                                                }*/
1516                                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
1517                                break;
1518
1519                                case CMDTHREAD_RESET_BULK_IN:
1520                                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
1521
1522                                        // All transfers must be aborted or cancelled before attempting to reset the pipe.
1523                                        {
1524                                                UINT32          MACValue;
1525/*-----------------------------------------------------------------------------------------------*/
1526/*-----------------------------------------------------------------------------------------------*/
1527                                                {
1528                                                //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1529                                                if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1530                                                {
1531                                                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
1532                                                        RTUSBCancelPendingBulkInIRP(pAd);
1533                                                        RTMPusecDelay(100000);
1534                                                        pAd->PendingRx = 0;
1535                                                }
1536                                                }
1537
1538                                                // Wait 10ms before reading register.
1539                                                RTMPusecDelay(10000);
1540                                                ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
1541
1542                                                if ((NT_SUCCESS(ntStatus) == TRUE) &&
1543                                                        (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1544                                                                                                        fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
1545                                                {
1546                                                        UCHAR   i;
1547
1548                                                        if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1549                                                                                                                fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
1550                                                                break;
1551                                                        pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
1552                                                        DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
1553                                                                        pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
1554                                                        for (i = 0; i < RX_RING_SIZE; i++)
1555                                                        {
1556                                                                DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
1557                                                                        , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
1558                                                        }
1559                                                        /*
1560
1561                                                        DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
1562
1563                                                        pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1564                                                        pAd->NextRxBulkInIndex          = 0;    // Rx Bulk pointer
1565                                                        for (i = 0; i < (RX_RING_SIZE); i++)
1566                                                        {
1567                                                                PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
1568
1569                                                                pRxContext->pAd = pAd;
1570                                                                pRxContext->InUse               = FALSE;
1571                                                                pRxContext->IRPPending  = FALSE;
1572                                                                pRxContext->Readable    = FALSE;
1573                                                                pRxContext->ReorderInUse = FALSE;
1574
1575                                                        }*/
1576                                                        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1577                                                        for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
1578                                                        {
1579                                                                //RTUSBBulkReceive(pAd);
1580                                                                PRX_CONTEXT             pRxContext;
1581                                                                PURB                    pUrb;
1582                                                                int                             ret = 0;
1583                                                                unsigned long   IrqFlags;
1584
1585
1586                                                                RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1587                                                                pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1588                                                                if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1589                                                                {
1590                                                                        RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1591                                                                        break;
1592                                                                }
1593                                                                pRxContext->InUse = TRUE;
1594                                                                pRxContext->IRPPending = TRUE;
1595                                                                pAd->PendingRx++;
1596                                                                pAd->BulkInReq++;
1597                                                                RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1598
1599                                                                // Init Rx context descriptor
1600                                                                RTUSBInitRxDesc(pAd, pRxContext);
1601                                                                pUrb = pRxContext->pUrb;
1602                                                                if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1603                                                                {       // fail
1604
1605                                                                        RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1606                                                                        pRxContext->InUse = FALSE;
1607                                                                        pRxContext->IRPPending = FALSE;
1608                                                                        pAd->PendingRx--;
1609                                                                        pAd->BulkInReq--;
1610                                                                        RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1611                                                                        DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
1612                                                                }
1613                                                                else
1614                                                                {       // success
1615                                                                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
1616                                                                        ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1617                                                                }
1618                                                        }
1619
1620                                                }
1621                                                else
1622                                                {
1623                                                        // Card must be removed
1624                                                        if (NT_SUCCESS(ntStatus) != TRUE)
1625                                                        {
1626                                                        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
1627                                                                DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
1628                                                        }
1629                                                        else
1630                                                        {
1631                                                                DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
1632                                                }
1633                                        }
1634                                        }
1635                                        DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
1636                                        break;
1637
1638                                case CMDTHREAD_SET_ASIC_WCID:
1639                                        {
1640                                                RT_SET_ASIC_WCID        SetAsicWcid;
1641                                                USHORT          offset;
1642                                                UINT32          MACValue, MACRValue = 0;
1643                                                SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
1644
1645                                                if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
1646                                                        return;
1647
1648                                                offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
1649
1650                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
1651                                                MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
1652                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
1653                                                RTUSBWriteMACRegister(pAd, offset, MACValue);
1654                                                // Read bitmask
1655                                                RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
1656                                                if ( SetAsicWcid.DeleteTid != 0xffffffff)
1657                                                        MACRValue &= (~SetAsicWcid.DeleteTid);
1658                                                if (SetAsicWcid.SetTid != 0xffffffff)
1659                                                        MACRValue |= (SetAsicWcid.SetTid);
1660                                                MACRValue &= 0xffff0000;
1661
1662                                                MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
1663                                                MACValue |= MACRValue;
1664                                                RTUSBWriteMACRegister(pAd, offset+4, MACValue);
1665
1666                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
1667                                        }
1668                                        break;
1669
1670                                case CMDTHREAD_SET_ASIC_WCID_CIPHER:
1671                                        {
1672                                                RT_SET_ASIC_WCID_ATTRI  SetAsicWcidAttri;
1673                                                USHORT          offset;
1674                                                UINT32          MACRValue = 0;
1675                                                SHAREDKEY_MODE_STRUC csr1;
1676                                                SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
1677
1678                                                if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
1679                                                        return;
1680
1681                                                offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
1682
1683                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
1684                                                // Read bitmask
1685                                                RTUSBReadMACRegister(pAd, offset, &MACRValue);
1686                                                MACRValue = 0;
1687                                                MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1688
1689                                                RTUSBWriteMACRegister(pAd, offset, MACRValue);
1690                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1691
1692                                                offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
1693                                                MACRValue = 0;
1694                                                if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
1695                                                        MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
1696                                                else
1697                                                        MACRValue |= (0x20000000);
1698                                                RTUSBWriteMACRegister(pAd, offset, MACRValue);
1699                                                DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1700
1701                                                //
1702                                                // Update cipher algorithm. WSTA always use BSS0
1703                                                //
1704                                                // for adhoc mode only ,because wep status slow than add key, when use zero config
1705                                                if (pAd->StaCfg.BssType == BSS_ADHOC )
1706                                                {
1707                                                        offset = MAC_WCID_ATTRIBUTE_BASE;
1708
1709                                                        RTUSBReadMACRegister(pAd, offset, &MACRValue);
1710                                                        MACRValue &= (~0xe);
1711                                                        MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1712
1713                                                        RTUSBWriteMACRegister(pAd, offset, MACRValue);
1714
1715                                                        //Update group key cipher,,because wep status slow than add key, when use zero config
1716                                                        RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
1717
1718                                                        csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
1719                                                        csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
1720
1721                                                        RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
1722                                                }
1723                                        }
1724                                        break;
1725                                case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
1726                                        {
1727                                                MAC_TABLE_ENTRY *pEntry;
1728                                                pEntry = (MAC_TABLE_ENTRY *)pData;
1729
1730                                                {
1731                                                        AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
1732                                                        if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
1733                                                        {
1734                                                                UINT32 uIV = 0;
1735                                                                PUCHAR  ptr;
1736
1737                                                                ptr = (PUCHAR) &uIV;
1738                                                                *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1739                                                                AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1740                                                                AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1741                                                        }
1742                                                        else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
1743                                                        {
1744                                                                UINT32 uIV = 0;
1745                                                                PUCHAR  ptr;
1746
1747                                                                ptr = (PUCHAR) &uIV;
1748                                                                *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1749                                                                AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1750                                                                AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1751                                                        }
1752                                                        else
1753                                                        {
1754                                                                //
1755                                                                // Other case, disable engine.
1756                                                                // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
1757                                                                //
1758                                                                USHORT   offset;
1759                                                                offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
1760                                                                // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
1761                                                                RTUSBWriteMACRegister(pAd, offset, 0);
1762                                                        }
1763                                                }
1764
1765                                                AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
1766                                                printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
1767                                                                pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
1768                                        }
1769                                        break;
1770                                case CMDTHREAD_UPDATE_PROTECT:
1771                                        {
1772                                                AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
1773                                        }
1774                                        break;
1775                                case OID_802_11_ADD_WEP:
1776                                        {
1777                                                UINT    i;
1778                                                UINT32  KeyIdx;
1779                                                PNDIS_802_11_WEP        pWepKey;
1780
1781                                                DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP  \n"));
1782
1783                                                pWepKey = (PNDIS_802_11_WEP)pData;
1784                                                KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
1785
1786                                                // it is a shared key
1787                                                if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
1788                                                {
1789                                                        NdisStatus = NDIS_STATUS_INVALID_DATA;
1790                                                        DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
1791                                                }
1792                                                else
1793                                                {
1794                                                        UCHAR CipherAlg;
1795                                                        pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
1796                                                        NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
1797                                                        CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
1798
1799                                                        //
1800                                                        // Change the WEP cipher to CKIP cipher if CKIP KP on.
1801                                                        // Funk UI or Meetinghouse UI will add ckip key from this path.
1802                                                        //
1803
1804                                                        if (pAd->OpMode == OPMODE_STA)
1805                                                        {
1806                                                                pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1807                                                                pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1808                                                        }
1809                                                        pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
1810                                                        if (pWepKey->KeyIndex & 0x80000000)
1811                                                        {
1812                                                                // Default key for tx (shared key)
1813                                                                UCHAR   IVEIV[8];
1814                                                                UINT32  WCIDAttri, Value;
1815                                                                USHORT  offset, offset2;
1816                                                                NdisZeroMemory(IVEIV, 8);
1817                                                                pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
1818                                                                // Add BSSID to WCTable. because this is Tx wep key.
1819                                                                // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
1820                                                                WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
1821
1822                                                                offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
1823                                                                RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1824                                                                // 1. IV/EIV
1825                                                                // Specify key index to find shared key.
1826                                                                IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
1827                                                                offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1828                                                                offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
1829                                                                for (i=0; i<8;)
1830                                                                {
1831                                                                        Value = IVEIV[i];
1832                                                                        Value += (IVEIV[i+1]<<8);
1833                                                                        Value += (IVEIV[i+2]<<16);
1834                                                                        Value += (IVEIV[i+3]<<24);
1835                                                                        RTUSBWriteMACRegister(pAd, offset+i, Value);
1836                                                                        RTUSBWriteMACRegister(pAd, offset2+i, Value);
1837                                                                        i+=4;
1838                                                                }
1839
1840                                                                // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1841                                                                WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
1842                                                                offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1843                                                                DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
1844                                                                RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1845
1846                                                        }
1847                                                        AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
1848                                                        DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
1849                                                }
1850                                        }
1851                                        break;
1852
1853                                case CMDTHREAD_802_11_COUNTER_MEASURE:
1854                                        break;
1855                                default:
1856                                        DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
1857                                        break;
1858                        }
1859                }
1860
1861                if (cmdqelmt->CmdFromNdis == TRUE)
1862                {
1863                                if (cmdqelmt->buffer != NULL)
1864                                        NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1865
1866                        NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1867                }
1868                else
1869                {
1870                        if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
1871                                NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1872            {
1873                                NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1874                        }
1875                }
1876        }       /* end of while */
1877}
1878
1879