Staging: rt3070: remove dead CONFIG_AP_SUPPORT code
[linux-2.6] / drivers / staging / rt3070 / common / rtusb_io.c
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
58 NTSTATUS        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 */
93 NTSTATUS 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 */
138 NTSTATUS        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 }
155 NTSTATUS        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 */
188 NTSTATUS        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 */
224 NTSTATUS        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
245 NTSTATUS        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
273 NTSTATUS 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 */
310 NTSTATUS        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 */
353 NTSTATUS        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 */
387 NTSTATUS        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 */
475 NTSTATUS        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 */
535 NTSTATUS        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
592 NTSTATUS        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 */
639 NTSTATUS        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
676         Routine Description:
677
678         Arguments:
679
680         Return Value:
681
682         IRQL =
683
684         Note:
685
686         ========================================================================
687 */
688 NTSTATUS        RTUSBReadEEPROM(
689         IN      PRTMP_ADAPTER   pAd,
690         IN      USHORT                  Offset,
691         OUT     PUCHAR                  pData,
692         IN      USHORT                  length)
693 {
694         NTSTATUS        Status = STATUS_SUCCESS;
695
696 #ifdef RT30xx
697         if(pAd->bUseEfuse)
698         {
699                 Status =eFuseRead(pAd, Offset, pData, length);
700         }
701         else
702 #endif // RT30xx //
703         {
704         Status = RTUSB_VendorRequest(
705                 pAd,
706                 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
707                 DEVICE_VENDOR_REQUEST_IN,
708                 0x9,
709                 0,
710                 Offset,
711                 pData,
712                 length);
713         }
714
715         return Status;
716 }
717
718 /*
719         ========================================================================
720
721         Routine Description:
722
723         Arguments:
724
725         Return Value:
726
727         IRQL =
728
729         Note:
730
731         ========================================================================
732 */
733 NTSTATUS        RTUSBWriteEEPROM(
734         IN      PRTMP_ADAPTER   pAd,
735         IN      USHORT                  Offset,
736         IN      PUCHAR                  pData,
737         IN      USHORT                  length)
738 {
739         NTSTATUS        Status = STATUS_SUCCESS;
740
741 #ifdef RT30xx
742         if(pAd->bUseEfuse)
743         {
744                 Status = eFuseWrite(pAd, Offset, pData, length);
745         }
746         else
747 #endif // RT30xx //
748         {
749         Status = RTUSB_VendorRequest(
750                 pAd,
751                 USBD_TRANSFER_DIRECTION_OUT,
752                 DEVICE_VENDOR_REQUEST_OUT,
753                 0x8,
754                 0,
755                 Offset,
756                 pData,
757                 length);
758         }
759
760         return Status;
761 }
762
763 /*
764         ========================================================================
765
766         Routine Description:
767
768         Arguments:
769
770         Return Value:
771
772         IRQL =
773
774         Note:
775
776         ========================================================================
777 */
778 VOID RTUSBPutToSleep(
779         IN      PRTMP_ADAPTER   pAd)
780 {
781         UINT32          value;
782
783         // Timeout 0x40 x 50us
784         value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
785         RTUSBWriteMACRegister(pAd, 0x7010, value);
786         RTUSBWriteMACRegister(pAd, 0x404, 0x30);
787         //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
788         DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
789
790 }
791
792 /*
793         ========================================================================
794
795         Routine Description:
796
797         Arguments:
798
799         Return Value:
800
801         IRQL =
802
803         Note:
804
805         ========================================================================
806 */
807 NTSTATUS RTUSBWakeUp(
808         IN      PRTMP_ADAPTER   pAd)
809 {
810         NTSTATUS        Status;
811
812         Status = RTUSB_VendorRequest(
813                 pAd,
814                 USBD_TRANSFER_DIRECTION_OUT,
815                 DEVICE_VENDOR_REQUEST_OUT,
816                 0x01,
817                 0x09,
818                 0,
819                 NULL,
820                 0);
821
822         return Status;
823 }
824
825 /*
826         ========================================================================
827
828         Routine Description:
829
830         Arguments:
831
832         Return Value:
833
834         IRQL =
835
836         Note:
837
838         ========================================================================
839 */
840 VOID    RTUSBInitializeCmdQ(
841         IN      PCmdQ   cmdq)
842 {
843         cmdq->head = NULL;
844         cmdq->tail = NULL;
845         cmdq->size = 0;
846         cmdq->CmdQState = RT2870_THREAD_INITED;
847 }
848
849 /*
850         ========================================================================
851
852         Routine Description:
853
854         Arguments:
855
856         Return Value:
857
858         IRQL =
859
860         Note:
861
862         ========================================================================
863 */
864 NDIS_STATUS     RTUSBEnqueueCmdFromNdis(
865         IN      PRTMP_ADAPTER   pAd,
866         IN      NDIS_OID                Oid,
867         IN      BOOLEAN                 SetInformation,
868         IN      PVOID                   pInformationBuffer,
869         IN      UINT32                  InformationBufferLength)
870 {
871         NDIS_STATUS     status;
872         PCmdQElmt       cmdqelmt = NULL;
873         POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
874
875
876         if (pObj->RTUSBCmdThr_pid < 0)
877                 return (NDIS_STATUS_RESOURCES);
878
879         status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
880         if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
881                 return (NDIS_STATUS_RESOURCES);
882
883                 cmdqelmt->buffer = NULL;
884                 if (pInformationBuffer != NULL)
885                 {
886                         status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
887                         if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
888                         {
889                                 kfree(cmdqelmt);
890                                 return (NDIS_STATUS_RESOURCES);
891                         }
892                         else
893                         {
894                                 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
895                                 cmdqelmt->bufferlength = InformationBufferLength;
896                         }
897                 }
898                 else
899                         cmdqelmt->bufferlength = 0;
900
901         cmdqelmt->command = Oid;
902         cmdqelmt->CmdFromNdis = TRUE;
903         if (SetInformation == TRUE)
904                 cmdqelmt->SetOperation = TRUE;
905         else
906                 cmdqelmt->SetOperation = FALSE;
907
908         NdisAcquireSpinLock(&pAd->CmdQLock);
909         if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
910         {
911                 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
912                 status = NDIS_STATUS_SUCCESS;
913         }
914         else
915         {
916                 status = NDIS_STATUS_FAILURE;
917         }
918         NdisReleaseSpinLock(&pAd->CmdQLock);
919
920         if (status == NDIS_STATUS_FAILURE)
921         {
922                 if (cmdqelmt->buffer)
923                         NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
924                 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
925         }
926         else
927         RTUSBCMDUp(pAd);
928
929
930     return(NDIS_STATUS_SUCCESS);
931 }
932
933 /*
934         ========================================================================
935
936         Routine Description:
937
938         Arguments:
939
940         Return Value:
941
942         IRQL =
943
944         Note:
945
946         ========================================================================
947 */
948 NDIS_STATUS RTUSBEnqueueInternalCmd(
949         IN PRTMP_ADAPTER        pAd,
950         IN NDIS_OID                     Oid,
951         IN PVOID                        pInformationBuffer,
952         IN UINT32                       InformationBufferLength)
953 {
954         NDIS_STATUS     status;
955         PCmdQElmt       cmdqelmt = NULL;
956
957
958         status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
959         if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
960                 return (NDIS_STATUS_RESOURCES);
961         NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
962
963         if(InformationBufferLength > 0)
964         {
965                 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
966                 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
967                 {
968                         NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
969                         return (NDIS_STATUS_RESOURCES);
970                 }
971                 else
972                 {
973                         NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
974                         cmdqelmt->bufferlength = InformationBufferLength;
975                 }
976         }
977         else
978         {
979                 cmdqelmt->buffer = NULL;
980                 cmdqelmt->bufferlength = 0;
981         }
982
983         cmdqelmt->command = Oid;
984         cmdqelmt->CmdFromNdis = FALSE;
985
986         if (cmdqelmt != NULL)
987         {
988                 NdisAcquireSpinLock(&pAd->CmdQLock);
989                 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
990                 {
991                         EnqueueCmd((&pAd->CmdQ), cmdqelmt);
992                         status = NDIS_STATUS_SUCCESS;
993                 }
994                 else
995                 {
996                         status = NDIS_STATUS_FAILURE;
997                 }
998                 NdisReleaseSpinLock(&pAd->CmdQLock);
999
1000                 if (status == NDIS_STATUS_FAILURE)
1001                 {
1002                         if (cmdqelmt->buffer)
1003                                 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1004                         NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1005                 }
1006                 else
1007                 RTUSBCMDUp(pAd);
1008         }
1009         return(NDIS_STATUS_SUCCESS);
1010 }
1011
1012 /*
1013         ========================================================================
1014
1015         Routine Description:
1016
1017         Arguments:
1018
1019         Return Value:
1020
1021         IRQL =
1022
1023         Note:
1024
1025         ========================================================================
1026 */
1027 VOID    RTUSBDequeueCmd(
1028         IN      PCmdQ           cmdq,
1029         OUT     PCmdQElmt       *pcmdqelmt)
1030 {
1031         *pcmdqelmt = cmdq->head;
1032
1033         if (*pcmdqelmt != NULL)
1034         {
1035                 cmdq->head = cmdq->head->next;
1036                 cmdq->size--;
1037                 if (cmdq->size == 0)
1038                         cmdq->tail = NULL;
1039         }
1040 }
1041
1042 /*
1043     ========================================================================
1044           usb_control_msg - Builds a control urb, sends it off and waits for completion
1045           @dev: pointer to the usb device to send the message to
1046           @pipe: endpoint "pipe" to send the message to
1047           @request: USB message request value
1048           @requesttype: USB message request type value
1049           @value: USB message value
1050           @index: USB message index value
1051           @data: pointer to the data to send
1052           @size: length in bytes of the data to send
1053           @timeout: time in jiffies to wait for the message to complete before
1054                           timing out (if 0 the wait is forever)
1055           Context: !in_interrupt ()
1056
1057           This function sends a simple control message to a specified endpoint
1058           and waits for the message to complete, or timeout.
1059           If successful, it returns the number of bytes transferred, otherwise a negative error number.
1060
1061          Don't use this function from within an interrupt context, like a
1062           bottom half handler.  If you need an asynchronous message, or need to send
1063           a message from within interrupt context, use usb_submit_urb()
1064           If a thread in your driver uses this call, make sure your disconnect()
1065           method can wait for it to complete.  Since you don't have a handle on
1066           the URB used, you can't cancel the request.
1067
1068
1069         Routine Description:
1070
1071         Arguments:
1072
1073         Return Value:
1074
1075         Note:
1076
1077         ========================================================================
1078 */
1079 NTSTATUS    RTUSB_VendorRequest(
1080         IN      PRTMP_ADAPTER   pAd,
1081         IN      UINT32                  TransferFlags,
1082         IN      UCHAR                   RequestType,
1083         IN      UCHAR                   Request,
1084         IN      USHORT                  Value,
1085         IN      USHORT                  Index,
1086         IN      PVOID                   TransferBuffer,
1087         IN      UINT32                  TransferBufferLength)
1088 {
1089         int                             ret;
1090         POS_COOKIE              pObj = (POS_COOKIE) pAd->OS_Cookie;
1091
1092         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1093         {
1094                 DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
1095                 return -1;
1096         }
1097         else if (in_interrupt())
1098         {
1099                 DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
1100
1101                 return -1;
1102         }
1103         else
1104         {
1105 #define MAX_RETRY_COUNT  10
1106
1107                 int retryCount = 0;
1108                 void    *tmpBuf = TransferBuffer;
1109
1110                 // Acquire Control token
1111                 do {
1112                 if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1113                         ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1114                 else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1115                         ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1116                 else
1117                 {
1118                         DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
1119                         ret = -1;
1120                 }
1121
1122                         retryCount++;
1123                         if (ret < 0) {
1124                                 printk("#\n");
1125                                 RTMPusecDelay(5000);
1126                         }
1127                 } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
1128
1129         if (ret < 0) {
1130 //                      DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
1131                         DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
1132                                                 ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
1133                         if (Request == 0x2)
1134                                 DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
1135
1136                         if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
1137                                 hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
1138         }
1139         }
1140         return ret;
1141 }
1142
1143 /*
1144         ========================================================================
1145
1146         Routine Description:
1147           Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
1148           synchronously. Callers of this function must be running at
1149           PASSIVE LEVEL.
1150
1151         Arguments:
1152
1153         Return Value:
1154
1155         Note:
1156
1157         ========================================================================
1158 */
1159 NTSTATUS        RTUSB_ResetDevice(
1160         IN      PRTMP_ADAPTER   pAd)
1161 {
1162         NTSTATUS                Status = TRUE;
1163
1164         DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
1165         //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
1166         return Status;
1167 }
1168
1169 VOID CMDHandler(
1170     IN PRTMP_ADAPTER pAd)
1171 {
1172         PCmdQElmt               cmdqelmt;
1173         PUCHAR                  pData;
1174         NDIS_STATUS             NdisStatus = NDIS_STATUS_SUCCESS;
1175 //      ULONG                   Now = 0;
1176         NTSTATUS                ntStatus;
1177 //      unsigned long   IrqFlags;
1178
1179         while (pAd->CmdQ.size > 0)
1180         {
1181                 NdisStatus = NDIS_STATUS_SUCCESS;
1182
1183                 NdisAcquireSpinLock(&pAd->CmdQLock);
1184                 RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
1185                 NdisReleaseSpinLock(&pAd->CmdQLock);
1186
1187                 if (cmdqelmt == NULL)
1188                         break;
1189
1190                 pData = cmdqelmt->buffer;
1191
1192                 if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1193                 {
1194                         switch (cmdqelmt->command)
1195                         {
1196                                 case CMDTHREAD_CHECK_GPIO:
1197                                         {
1198                                                 UINT32 data;
1199
1200                                                 {
1201                                                         // Read GPIO pin2 as Hardware controlled radio state
1202
1203                                                         RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
1204
1205                                                         if (data & 0x04)
1206                                                         {
1207                                                                 pAd->StaCfg.bHwRadio = TRUE;
1208                                                         }
1209                                                         else
1210                                                         {
1211                                                                 pAd->StaCfg.bHwRadio = FALSE;
1212                                                         }
1213
1214                                                         if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1215                                                         {
1216                                                                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1217                                                                 if(pAd->StaCfg.bRadio == TRUE)
1218                                                                 {
1219                                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
1220
1221                                                                         MlmeRadioOn(pAd);
1222                                                                         // Update extra information
1223                                                                         pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1224                                                                 }
1225                                                                 else
1226                                                                 {
1227                                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
1228
1229                                                                         MlmeRadioOff(pAd);
1230                                                                         // Update extra information
1231                                                                         pAd->ExtraInfo = HW_RADIO_OFF;
1232                                                                 }
1233                                                         }
1234                                                 }
1235                                         }
1236                                         break;
1237
1238                                 case CMDTHREAD_QKERIODIC_EXECUT:
1239                                         {
1240                                                 StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
1241                                         }
1242                                         break;
1243
1244                                 case CMDTHREAD_RESET_BULK_OUT:
1245                                         {
1246                                                 UINT32          MACValue;
1247                                                 UCHAR           Index;
1248                                                 int                     ret=0;
1249                                                 PHT_TX_CONTEXT  pHTTXContext;
1250 //                                              RTMP_TX_RING *pTxRing;
1251                                                 unsigned long IrqFlags;
1252                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
1253                                                 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1254                                                 //RTUSBCancelPendingBulkOutIRP(pAd);
1255                                                 // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
1256                                                 Index = 0;
1257                                                 do
1258                                                 {
1259                                                         RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
1260                                                         if ((MACValue & 0xf00000/*0x800000*/) == 0)
1261                                                                 break;
1262                                                         Index++;
1263                                                         RTMPusecDelay(10000);
1264                                                 }while(Index < 100);
1265                                                 MACValue = 0;
1266                                                 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1267                                                 // To prevent Read Register error, we 2nd check the validity.
1268                                                 if ((MACValue & 0xc00000) == 0)
1269                                                         RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1270                                                 // To prevent Read Register error, we 3rd check the validity.
1271                                                 if ((MACValue & 0xc00000) == 0)
1272                                                         RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1273                                                 MACValue |= 0x80000;
1274                                                 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1275
1276                                                 // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1277                                                 RTMPusecDelay(1000);
1278
1279                                                 MACValue &= (~0x80000);
1280                                                 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1281                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
1282
1283                                                 // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1284                                                 //RTMPusecDelay(5000);
1285
1286                                                 if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
1287                                                 {
1288                                                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1289                                                         if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1290                                                         {
1291                                                                 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1292                                                         }
1293                                                         RTUSBKickBulkOut(pAd);
1294
1295                                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
1296                                                 }
1297                                                 else
1298                                                 {
1299                                                         pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
1300                                                         //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1301                                                         RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1302                                                         if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
1303                                                         {
1304                                                                 pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
1305                                                                 pHTTXContext->IRPPending = TRUE;
1306                                                                 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
1307
1308                                                                 // no matter what, clean the flag
1309                                                                 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1310
1311                                                                 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1312                                                                 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1313 /*-----------------------------------------------------------------------------------------------*/
1314 /*-----------------------------------------------------------------------------------------------*/
1315                                                                 {
1316                                                                 RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
1317
1318                                                                 if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
1319                                                                 {
1320                                                                                 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1321                                                                         pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
1322                                                                         pHTTXContext->IRPPending = FALSE;
1323                                                                                 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
1324                                                                                 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1325
1326                                                                                 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
1327                                                                 }
1328                                                                         else
1329                                                                         {
1330                                                                                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1331                                                                                 DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
1332                                                                                                 pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
1333                                                                                                                         pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
1334                                                                                 DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
1335                                                                                                                         pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1336                                                                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1337                                                                                 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));
1338
1339                                                                         }
1340                                                                 }
1341                                                         }
1342                                                         else
1343                                                         {
1344                                                                 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1345                                                                 //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1346
1347                                                                 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));
1348                                                                 if (pAd->bulkResetPipeid == 0)
1349                                                                 {
1350                                                                         UCHAR   pendingContext = 0;
1351                                                                         PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
1352                                                                         PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
1353                                                                         PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
1354                                                                         PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
1355
1356                                                                         if (pHTTXContext->IRPPending)
1357                                                                                 pendingContext |= 1;
1358                                                                         else if (pMLMEContext->IRPPending)
1359                                                                                 pendingContext |= 2;
1360                                                                         else if (pNULLContext->IRPPending)
1361                                                                                 pendingContext |= 4;
1362                                                                         else if (pPsPollContext->IRPPending)
1363                                                                                 pendingContext |= 8;
1364                                                                         else
1365                                                                                 pendingContext = 0;
1366
1367                                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
1368                                                                 }
1369
1370                                                         // no matter what, clean the flag
1371                                                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1372
1373                                                                 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1374
1375                                                                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
1376                                                         }
1377
1378                                                         RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1379                                                         //RTUSBKickBulkOut(pAd);
1380                                                 }
1381
1382                                         }
1383                                         /*
1384                                                 // Don't cancel BULKIN.
1385                                                 while ((atomic_read(&pAd->PendingRx) > 0) &&
1386                                                                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1387                                                 {
1388                                                         if (atomic_read(&pAd->PendingRx) > 0)
1389                                                         {
1390                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
1391                                                                 RTUSBCancelPendingBulkInIRP(pAd);
1392                                                         }
1393                                                         RTMPusecDelay(100000);
1394                                                 }
1395
1396                                                 if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1397                                                 {
1398                                                         UCHAR   i;
1399                                                         RTUSBRxPacket(pAd);
1400                                                         pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1401                                                         pAd->NextRxBulkInIndex          = 0;    // Rx Bulk pointer
1402                                                         for (i = 0; i < (RX_RING_SIZE); i++)
1403                                                         {
1404                                                                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
1405
1406                                                                 pRxContext->pAd = pAd;
1407                                                                 pRxContext->InUse               = FALSE;
1408                                                                 pRxContext->IRPPending  = FALSE;
1409                                                                 pRxContext->Readable    = FALSE;
1410                                                                 pRxContext->ReorderInUse = FALSE;
1411
1412                                                         }
1413                                                         RTUSBBulkReceive(pAd);
1414                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
1415                                                 }*/
1416                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
1417                                 break;
1418
1419                                 case CMDTHREAD_RESET_BULK_IN:
1420                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
1421
1422                                         // All transfers must be aborted or cancelled before attempting to reset the pipe.
1423                                         {
1424                                                 UINT32          MACValue;
1425 /*-----------------------------------------------------------------------------------------------*/
1426 /*-----------------------------------------------------------------------------------------------*/
1427                                                 {
1428                                                 //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1429                                                 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1430                                                 {
1431                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
1432                                                         RTUSBCancelPendingBulkInIRP(pAd);
1433                                                         RTMPusecDelay(100000);
1434                                                         pAd->PendingRx = 0;
1435                                                 }
1436                                                 }
1437
1438                                                 // Wait 10ms before reading register.
1439                                                 RTMPusecDelay(10000);
1440                                                 ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
1441
1442                                                 if ((NT_SUCCESS(ntStatus) == TRUE) &&
1443                                                         (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1444                                                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
1445                                                 {
1446                                                         UCHAR   i;
1447
1448                                                         if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1449                                                                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
1450                                                                 break;
1451                                                         pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
1452                                                         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",
1453                                                                         pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
1454                                                         for (i = 0; i < RX_RING_SIZE; i++)
1455                                                         {
1456                                                                 DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
1457                                                                         , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
1458                                                         }
1459                                                         /*
1460
1461                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
1462
1463                                                         pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1464                                                         pAd->NextRxBulkInIndex          = 0;    // Rx Bulk pointer
1465                                                         for (i = 0; i < (RX_RING_SIZE); i++)
1466                                                         {
1467                                                                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
1468
1469                                                                 pRxContext->pAd = pAd;
1470                                                                 pRxContext->InUse               = FALSE;
1471                                                                 pRxContext->IRPPending  = FALSE;
1472                                                                 pRxContext->Readable    = FALSE;
1473                                                                 pRxContext->ReorderInUse = FALSE;
1474
1475                                                         }*/
1476                                                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1477                                                         for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
1478                                                         {
1479                                                                 //RTUSBBulkReceive(pAd);
1480                                                                 PRX_CONTEXT             pRxContext;
1481                                                                 PURB                    pUrb;
1482                                                                 int                             ret = 0;
1483                                                                 unsigned long   IrqFlags;
1484
1485
1486                                                                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1487                                                                 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1488                                                                 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1489                                                                 {
1490                                                                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1491                                                                         break;
1492                                                                 }
1493                                                                 pRxContext->InUse = TRUE;
1494                                                                 pRxContext->IRPPending = TRUE;
1495                                                                 pAd->PendingRx++;
1496                                                                 pAd->BulkInReq++;
1497                                                                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1498
1499                                                                 // Init Rx context descriptor
1500                                                                 RTUSBInitRxDesc(pAd, pRxContext);
1501                                                                 pUrb = pRxContext->pUrb;
1502                                                                 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1503                                                                 {       // fail
1504
1505                                                                         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1506                                                                         pRxContext->InUse = FALSE;
1507                                                                         pRxContext->IRPPending = FALSE;
1508                                                                         pAd->PendingRx--;
1509                                                                         pAd->BulkInReq--;
1510                                                                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1511                                                                         DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
1512                                                                 }
1513                                                                 else
1514                                                                 {       // success
1515                                                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
1516                                                                         ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1517                                                                 }
1518                                                         }
1519
1520                                                 }
1521                                                 else
1522                                                 {
1523                                                         // Card must be removed
1524                                                         if (NT_SUCCESS(ntStatus) != TRUE)
1525                                                         {
1526                                                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
1527                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
1528                                                         }
1529                                                         else
1530                                                         {
1531                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
1532                                                 }
1533                                         }
1534                                         }
1535                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
1536                                         break;
1537
1538                                 case CMDTHREAD_SET_ASIC_WCID:
1539                                         {
1540                                                 RT_SET_ASIC_WCID        SetAsicWcid;
1541                                                 USHORT          offset;
1542                                                 UINT32          MACValue, MACRValue = 0;
1543                                                 SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
1544
1545                                                 if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
1546                                                         return;
1547
1548                                                 offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
1549
1550                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
1551                                                 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]);
1552                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
1553                                                 RTUSBWriteMACRegister(pAd, offset, MACValue);
1554                                                 // Read bitmask
1555                                                 RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
1556                                                 if ( SetAsicWcid.DeleteTid != 0xffffffff)
1557                                                         MACRValue &= (~SetAsicWcid.DeleteTid);
1558                                                 if (SetAsicWcid.SetTid != 0xffffffff)
1559                                                         MACRValue |= (SetAsicWcid.SetTid);
1560                                                 MACRValue &= 0xffff0000;
1561
1562                                                 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
1563                                                 MACValue |= MACRValue;
1564                                                 RTUSBWriteMACRegister(pAd, offset+4, MACValue);
1565
1566                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
1567                                         }
1568                                         break;
1569
1570                                 case CMDTHREAD_SET_ASIC_WCID_CIPHER:
1571                                         {
1572                                                 RT_SET_ASIC_WCID_ATTRI  SetAsicWcidAttri;
1573                                                 USHORT          offset;
1574                                                 UINT32          MACRValue = 0;
1575                                                 SHAREDKEY_MODE_STRUC csr1;
1576                                                 SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
1577
1578                                                 if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
1579                                                         return;
1580
1581                                                 offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
1582
1583                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
1584                                                 // Read bitmask
1585                                                 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1586                                                 MACRValue = 0;
1587                                                 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1588
1589                                                 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1590                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1591
1592                                                 offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
1593                                                 MACRValue = 0;
1594                                                 if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
1595                                                         MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
1596                                                 else
1597                                                         MACRValue |= (0x20000000);
1598                                                 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1599                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1600
1601                                                 //
1602                                                 // Update cipher algorithm. WSTA always use BSS0
1603                                                 //
1604                                                 // for adhoc mode only ,because wep status slow than add key, when use zero config
1605                                                 if (pAd->StaCfg.BssType == BSS_ADHOC )
1606                                                 {
1607                                                         offset = MAC_WCID_ATTRIBUTE_BASE;
1608
1609                                                         RTUSBReadMACRegister(pAd, offset, &MACRValue);
1610                                                         MACRValue &= (~0xe);
1611                                                         MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1612
1613                                                         RTUSBWriteMACRegister(pAd, offset, MACRValue);
1614
1615                                                         //Update group key cipher,,because wep status slow than add key, when use zero config
1616                                                         RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
1617
1618                                                         csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
1619                                                         csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
1620
1621                                                         RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
1622                                                 }
1623                                         }
1624                                         break;
1625
1626 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1627                                 case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
1628                                 {
1629                                         RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1630                                         KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
1631                                         AsicAddPairwiseKeyEntry(pAd,
1632                                                                                         KeyInfo.MacAddr,
1633                                                                                         (UCHAR)KeyInfo.MacTabMatchWCID,
1634                                                                                         &KeyInfo.CipherKey);
1635                                 }
1636                                         break;
1637                                 case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
1638                                 {
1639                                         PMAC_TABLE_ENTRY pEntry;
1640                                         UCHAR KeyIdx;
1641                                         UCHAR CipherAlg;
1642                                         UCHAR ApIdx;
1643
1644                                         pEntry = (PMAC_TABLE_ENTRY)(pData);
1645
1646                                                 RTMPAddWcidAttributeEntry(
1647                                                                                   pAd,
1648                                                                                   ApIdx,
1649                                                                                   KeyIdx,
1650                                                                                   CipherAlg,
1651                                                                                   pEntry);
1652                                         }
1653                                                 break;
1654 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1655
1656                                 case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
1657                                         {
1658                                                 MAC_TABLE_ENTRY *pEntry;
1659                                                 pEntry = (MAC_TABLE_ENTRY *)pData;
1660
1661                                                 {
1662                                                         AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
1663                                                         if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
1664                                                         {
1665                                                                 UINT32 uIV = 0;
1666                                                                 PUCHAR  ptr;
1667
1668                                                                 ptr = (PUCHAR) &uIV;
1669                                                                 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1670                                                                 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1671                                                                 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1672                                                         }
1673                                                         else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
1674                                                         {
1675                                                                 UINT32 uIV = 0;
1676                                                                 PUCHAR  ptr;
1677
1678                                                                 ptr = (PUCHAR) &uIV;
1679                                                                 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1680                                                                 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1681                                                                 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1682                                                         }
1683                                                         else
1684                                                         {
1685                                                                 //
1686                                                                 // Other case, disable engine.
1687                                                                 // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
1688                                                                 //
1689                                                                 USHORT   offset;
1690                                                                 offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
1691                                                                 // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
1692                                                                 RTUSBWriteMACRegister(pAd, offset, 0);
1693                                                         }
1694                                                 }
1695
1696                                                 AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
1697                                                 printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
1698                                                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
1699                                         }
1700                                         break;
1701
1702 // add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
1703                                 case CMDTHREAD_UPDATE_PROTECT:
1704                                         {
1705                                                 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
1706                                         }
1707                                         break;
1708 // end johnli
1709
1710                                 case OID_802_11_ADD_WEP:
1711                                         {
1712                                                 UINT    i;
1713                                                 UINT32  KeyIdx;
1714                                                 PNDIS_802_11_WEP        pWepKey;
1715
1716                                                 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP  \n"));
1717
1718                                                 pWepKey = (PNDIS_802_11_WEP)pData;
1719                                                 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
1720
1721                                                 // it is a shared key
1722                                                 if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
1723                                                 {
1724                                                         NdisStatus = NDIS_STATUS_INVALID_DATA;
1725                                                         DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
1726                                                 }
1727                                                 else
1728                                                 {
1729                                                         UCHAR CipherAlg;
1730                                                         pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
1731                                                         NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
1732                                                         CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
1733
1734                                                         //
1735                                                         // Change the WEP cipher to CKIP cipher if CKIP KP on.
1736                                                         // Funk UI or Meetinghouse UI will add ckip key from this path.
1737                                                         //
1738
1739                                                         if (pAd->OpMode == OPMODE_STA)
1740                                                         {
1741                                                                 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1742                                                                 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1743                                                         }
1744                                                         pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
1745                                                         if (pWepKey->KeyIndex & 0x80000000)
1746                                                         {
1747                                                                 // Default key for tx (shared key)
1748                                                                 UCHAR   IVEIV[8];
1749                                                                 UINT32  WCIDAttri, Value;
1750                                                                 USHORT  offset, offset2;
1751                                                                 NdisZeroMemory(IVEIV, 8);
1752                                                                 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
1753                                                                 // Add BSSID to WCTable. because this is Tx wep key.
1754                                                                 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
1755                                                                 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
1756
1757                                                                 offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
1758                                                                 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1759                                                                 // 1. IV/EIV
1760                                                                 // Specify key index to find shared key.
1761                                                                 IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
1762                                                                 offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1763                                                                 offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
1764                                                                 for (i=0; i<8;)
1765                                                                 {
1766                                                                         Value = IVEIV[i];
1767                                                                         Value += (IVEIV[i+1]<<8);
1768                                                                         Value += (IVEIV[i+2]<<16);
1769                                                                         Value += (IVEIV[i+3]<<24);
1770                                                                         RTUSBWriteMACRegister(pAd, offset+i, Value);
1771                                                                         RTUSBWriteMACRegister(pAd, offset2+i, Value);
1772                                                                         i+=4;
1773                                                                 }
1774
1775                                                                 // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1776                                                                 WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
1777                                                                 offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1778                                                                 DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
1779                                                                 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1780
1781                                                         }
1782                                                         AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
1783                                                         DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
1784                                                 }
1785                                         }
1786                                         break;
1787
1788                                 case CMDTHREAD_802_11_COUNTER_MEASURE:
1789                                         break;
1790
1791                                 default:
1792                                         DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
1793                                         break;
1794                         }
1795                 }
1796
1797                 if (cmdqelmt->CmdFromNdis == TRUE)
1798                 {
1799                                 if (cmdqelmt->buffer != NULL)
1800                                         NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1801
1802                         NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1803                 }
1804                 else
1805                 {
1806                         if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
1807                                 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1808             {
1809                                 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1810                         }
1811                 }
1812         }       /* end of while */
1813 }
1814