Merge branch 'for-linus' of git://neil.brown.name/md
[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 #ifdef INF_AMAZON_SE
1112                 ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
1113                 if (pAd->UsbVendorReqBuf)
1114                 {
1115                         ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
1116
1117                         tmpBuf = (void *)pAd->UsbVendorReqBuf;
1118                         NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
1119
1120                         if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
1121                          NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);
1122                 }
1123 #endif // INF_AMAZON_SE //
1124                 do {
1125                 if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1126                         ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1127                 else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1128                         ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1129                 else
1130                 {
1131                         DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
1132                         ret = -1;
1133                 }
1134
1135                         retryCount++;
1136                         if (ret < 0) {
1137                                 printk("#\n");
1138                                 RTMPusecDelay(5000);
1139                         }
1140                 } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
1141
1142 #ifdef INF_AMAZON_SE
1143                 if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
1144                         NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
1145                 up(&(pAd->UsbVendorReq_semaphore));
1146 #endif // INF_AMAZON_SE //
1147
1148         if (ret < 0) {
1149 //                      DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
1150                         DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
1151                                                 ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
1152                         if (Request == 0x2)
1153                                 DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
1154
1155                         if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
1156                                 hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
1157         }
1158         }
1159         return ret;
1160 }
1161
1162 /*
1163         ========================================================================
1164
1165         Routine Description:
1166           Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
1167           synchronously. Callers of this function must be running at
1168           PASSIVE LEVEL.
1169
1170         Arguments:
1171
1172         Return Value:
1173
1174         Note:
1175
1176         ========================================================================
1177 */
1178 NTSTATUS        RTUSB_ResetDevice(
1179         IN      PRTMP_ADAPTER   pAd)
1180 {
1181         NTSTATUS                Status = TRUE;
1182
1183         DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
1184         //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
1185         return Status;
1186 }
1187
1188 VOID CMDHandler(
1189     IN PRTMP_ADAPTER pAd)
1190 {
1191         PCmdQElmt               cmdqelmt;
1192         PUCHAR                  pData;
1193         NDIS_STATUS             NdisStatus = NDIS_STATUS_SUCCESS;
1194 //      ULONG                   Now = 0;
1195         NTSTATUS                ntStatus;
1196 //      unsigned long   IrqFlags;
1197
1198         while (pAd->CmdQ.size > 0)
1199         {
1200                 NdisStatus = NDIS_STATUS_SUCCESS;
1201
1202                 NdisAcquireSpinLock(&pAd->CmdQLock);
1203                 RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
1204                 NdisReleaseSpinLock(&pAd->CmdQLock);
1205
1206                 if (cmdqelmt == NULL)
1207                         break;
1208
1209                 pData = cmdqelmt->buffer;
1210
1211                 if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1212                 {
1213                         switch (cmdqelmt->command)
1214                         {
1215                                 case CMDTHREAD_CHECK_GPIO:
1216                                         {
1217 #ifdef CONFIG_STA_SUPPORT
1218                                                 UINT32 data;
1219 #endif // CONFIG_STA_SUPPORT //
1220 #ifdef RALINK_ATE
1221                                         if(ATE_ON(pAd))
1222                                                 {
1223                                                         DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
1224                                                         break;
1225                                                 }
1226 #endif // RALINK_ATE //
1227
1228 #ifdef CONFIG_STA_SUPPORT
1229
1230
1231                                                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1232                                                 {
1233                                                         // Read GPIO pin2 as Hardware controlled radio state
1234
1235                                                         RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
1236
1237                                                         if (data & 0x04)
1238                                                         {
1239                                                                 pAd->StaCfg.bHwRadio = TRUE;
1240                                                         }
1241                                                         else
1242                                                         {
1243                                                                 pAd->StaCfg.bHwRadio = FALSE;
1244                                                         }
1245
1246                                                         if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1247                                                         {
1248                                                                 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1249                                                                 if(pAd->StaCfg.bRadio == TRUE)
1250                                                                 {
1251                                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
1252
1253                                                                         MlmeRadioOn(pAd);
1254                                                                         // Update extra information
1255                                                                         pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1256                                                                 }
1257                                                                 else
1258                                                                 {
1259                                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
1260
1261                                                                         MlmeRadioOff(pAd);
1262                                                                         // Update extra information
1263                                                                         pAd->ExtraInfo = HW_RADIO_OFF;
1264                                                                 }
1265                                                         }
1266                                                 }
1267 #endif // CONFIG_STA_SUPPORT //
1268                                         }
1269                                         break;
1270
1271 #ifdef CONFIG_STA_SUPPORT
1272                                 case CMDTHREAD_QKERIODIC_EXECUT:
1273                                         {
1274                                                 StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
1275                                         }
1276                                         break;
1277 #endif // CONFIG_STA_SUPPORT //
1278
1279                                 case CMDTHREAD_RESET_BULK_OUT:
1280                                         {
1281                                                 UINT32          MACValue;
1282                                                 UCHAR           Index;
1283                                                 int                     ret=0;
1284                                                 PHT_TX_CONTEXT  pHTTXContext;
1285 //                                              RTMP_TX_RING *pTxRing;
1286                                                 unsigned long IrqFlags;
1287 #ifdef RALINK_ATE
1288                                                 PTX_CONTEXT             pNullContext = &(pAd->NullContext);
1289 #endif // RALINK_ATE //
1290                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
1291                                                 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1292                                                 //RTUSBCancelPendingBulkOutIRP(pAd);
1293                                                 // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
1294                                                 Index = 0;
1295                                                 do
1296                                                 {
1297                                                         RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
1298                                                         if ((MACValue & 0xf00000/*0x800000*/) == 0)
1299                                                                 break;
1300                                                         Index++;
1301                                                         RTMPusecDelay(10000);
1302                                                 }while(Index < 100);
1303                                                 MACValue = 0;
1304                                                 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1305                                                 // To prevent Read Register error, we 2nd check the validity.
1306                                                 if ((MACValue & 0xc00000) == 0)
1307                                                         RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1308                                                 // To prevent Read Register error, we 3rd check the validity.
1309                                                 if ((MACValue & 0xc00000) == 0)
1310                                                         RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1311                                                 MACValue |= 0x80000;
1312                                                 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1313
1314                                                 // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1315                                                 RTMPusecDelay(1000);
1316
1317                                                 MACValue &= (~0x80000);
1318                                                 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1319                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
1320
1321                                                 // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1322                                                 //RTMPusecDelay(5000);
1323
1324                                                 if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
1325                                                 {
1326                                                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1327                                                         if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1328                                                         {
1329                                                                 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1330                                                         }
1331                                                         RTUSBKickBulkOut(pAd);
1332
1333                                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
1334                                                 }
1335                                                 else
1336                                                 {
1337                                                         pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
1338                                                         //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1339                                                         RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1340                                                         if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
1341                                                         {
1342                                                                 pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
1343                                                                 pHTTXContext->IRPPending = TRUE;
1344                                                                 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
1345
1346                                                                 // no matter what, clean the flag
1347                                                                 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1348
1349                                                                 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1350                                                                 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1351 /*-----------------------------------------------------------------------------------------------*/
1352 #ifdef RALINK_ATE
1353                                                                 if(ATE_ON(pAd))
1354                                                             {
1355                                                                         pNullContext->IRPPending = TRUE;
1356                                                                         //
1357                                                                         // If driver is still in ATE TXFRAME mode,
1358                                                                         // keep on transmitting ATE frames.
1359                                                                         //
1360                                                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->ate.Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n", pAd->ate.Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained)));
1361                                                                         if((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0)))
1362                                                                     {
1363                                                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n"));
1364
1365                                                                                 // Init Tx context descriptor
1366                                                                                 RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
1367
1368                                                                                 if((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0)
1369                                                                                 {
1370                                                                                         DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
1371                                                                                 }
1372
1373                                                                                 pAd->BulkOutReq++;
1374                                                                         }
1375                                                                 }
1376                                                                 else
1377 #endif // RALINK_ATE //
1378 /*-----------------------------------------------------------------------------------------------*/
1379                                                                 {
1380                                                                 RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
1381
1382                                                                 if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
1383                                                                 {
1384                                                                                 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1385                                                                         pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
1386                                                                         pHTTXContext->IRPPending = FALSE;
1387                                                                                 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
1388                                                                                 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1389
1390                                                                                 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
1391                                                                 }
1392                                                                         else
1393                                                                         {
1394                                                                                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1395                                                                                 DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
1396                                                                                                 pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
1397                                                                                                                         pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
1398                                                                                 DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
1399                                                                                                                         pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1400                                                                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1401                                                                                 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));
1402
1403                                                                         }
1404                                                                 }
1405                                                         }
1406                                                         else
1407                                                         {
1408                                                                 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1409                                                                 //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1410
1411                                                                 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));
1412                                                                 if (pAd->bulkResetPipeid == 0)
1413                                                                 {
1414                                                                         UCHAR   pendingContext = 0;
1415                                                                         PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
1416                                                                         PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
1417                                                                         PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
1418                                                                         PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
1419
1420                                                                         if (pHTTXContext->IRPPending)
1421                                                                                 pendingContext |= 1;
1422                                                                         else if (pMLMEContext->IRPPending)
1423                                                                                 pendingContext |= 2;
1424                                                                         else if (pNULLContext->IRPPending)
1425                                                                                 pendingContext |= 4;
1426                                                                         else if (pPsPollContext->IRPPending)
1427                                                                                 pendingContext |= 8;
1428                                                                         else
1429                                                                                 pendingContext = 0;
1430
1431                                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
1432                                                                 }
1433
1434                                                         // no matter what, clean the flag
1435                                                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1436
1437                                                                 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1438
1439                                                                 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
1440                                                         }
1441
1442                                                         RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1443                                                         //RTUSBKickBulkOut(pAd);
1444                                                 }
1445
1446                                         }
1447                                         /*
1448                                                 // Don't cancel BULKIN.
1449                                                 while ((atomic_read(&pAd->PendingRx) > 0) &&
1450                                                                 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1451                                                 {
1452                                                         if (atomic_read(&pAd->PendingRx) > 0)
1453                                                         {
1454                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
1455                                                                 RTUSBCancelPendingBulkInIRP(pAd);
1456                                                         }
1457                                                         RTMPusecDelay(100000);
1458                                                 }
1459
1460                                                 if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1461                                                 {
1462                                                         UCHAR   i;
1463                                                         RTUSBRxPacket(pAd);
1464                                                         pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1465                                                         pAd->NextRxBulkInIndex          = 0;    // Rx Bulk pointer
1466                                                         for (i = 0; i < (RX_RING_SIZE); i++)
1467                                                         {
1468                                                                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
1469
1470                                                                 pRxContext->pAd = pAd;
1471                                                                 pRxContext->InUse               = FALSE;
1472                                                                 pRxContext->IRPPending  = FALSE;
1473                                                                 pRxContext->Readable    = FALSE;
1474                                                                 pRxContext->ReorderInUse = FALSE;
1475
1476                                                         }
1477                                                         RTUSBBulkReceive(pAd);
1478                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
1479                                                 }*/
1480                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
1481                                 break;
1482
1483                                 case CMDTHREAD_RESET_BULK_IN:
1484                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
1485
1486                                         // All transfers must be aborted or cancelled before attempting to reset the pipe.
1487                                         {
1488                                                 UINT32          MACValue;
1489 /*-----------------------------------------------------------------------------------------------*/
1490 #ifdef RALINK_ATE
1491                                                 if (ATE_ON(pAd))
1492                                                 {
1493                                                         if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1494                                                         {
1495                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n"));
1496                                                                 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1497                                                                 RTMPusecDelay(100000);
1498                                                                 pAd->PendingRx = 0;
1499                                                         }
1500                                                 }
1501                                                 else
1502 #endif // RALINK_ATE //
1503 /*-----------------------------------------------------------------------------------------------*/
1504                                                 {
1505                                                 //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1506                                                 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1507                                                 {
1508                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
1509                                                         RTUSBCancelPendingBulkInIRP(pAd);
1510                                                         RTMPusecDelay(100000);
1511                                                         pAd->PendingRx = 0;
1512                                                 }
1513                                                 }
1514
1515                                                 // Wait 10ms before reading register.
1516                                                 RTMPusecDelay(10000);
1517                                                 ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
1518
1519                                                 if ((NT_SUCCESS(ntStatus) == TRUE) &&
1520                                                         (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1521                                                                                                         fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
1522                                                 {
1523                                                         UCHAR   i;
1524
1525                                                         if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1526                                                                                                                 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
1527                                                                 break;
1528                                                         pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
1529                                                         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",
1530                                                                         pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
1531                                                         for (i = 0; i < RX_RING_SIZE; i++)
1532                                                         {
1533                                                                 DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
1534                                                                         , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
1535                                                         }
1536                                                         /*
1537
1538                                                         DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
1539
1540                                                         pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1541                                                         pAd->NextRxBulkInIndex          = 0;    // Rx Bulk pointer
1542                                                         for (i = 0; i < (RX_RING_SIZE); i++)
1543                                                         {
1544                                                                 PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
1545
1546                                                                 pRxContext->pAd = pAd;
1547                                                                 pRxContext->InUse               = FALSE;
1548                                                                 pRxContext->IRPPending  = FALSE;
1549                                                                 pRxContext->Readable    = FALSE;
1550                                                                 pRxContext->ReorderInUse = FALSE;
1551
1552                                                         }*/
1553                                                         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1554                                                         for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
1555                                                         {
1556                                                                 //RTUSBBulkReceive(pAd);
1557                                                                 PRX_CONTEXT             pRxContext;
1558                                                                 PURB                    pUrb;
1559                                                                 int                             ret = 0;
1560                                                                 unsigned long   IrqFlags;
1561
1562
1563                                                                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1564                                                                 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1565                                                                 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1566                                                                 {
1567                                                                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1568                                                                         break;
1569                                                                 }
1570                                                                 pRxContext->InUse = TRUE;
1571                                                                 pRxContext->IRPPending = TRUE;
1572                                                                 pAd->PendingRx++;
1573                                                                 pAd->BulkInReq++;
1574                                                                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1575
1576                                                                 // Init Rx context descriptor
1577                                                                 RTUSBInitRxDesc(pAd, pRxContext);
1578                                                                 pUrb = pRxContext->pUrb;
1579                                                                 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1580                                                                 {       // fail
1581
1582                                                                         RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1583                                                                         pRxContext->InUse = FALSE;
1584                                                                         pRxContext->IRPPending = FALSE;
1585                                                                         pAd->PendingRx--;
1586                                                                         pAd->BulkInReq--;
1587                                                                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1588                                                                         DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
1589                                                                 }
1590                                                                 else
1591                                                                 {       // success
1592                                                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
1593                                                                         ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1594                                                                 }
1595                                                         }
1596
1597                                                 }
1598                                                 else
1599                                                 {
1600                                                         // Card must be removed
1601                                                         if (NT_SUCCESS(ntStatus) != TRUE)
1602                                                         {
1603                                                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
1604                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
1605                                                         }
1606                                                         else
1607                                                         {
1608                                                                 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
1609                                                 }
1610                                         }
1611                                         }
1612                                         DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
1613                                         break;
1614
1615                                 case CMDTHREAD_SET_ASIC_WCID:
1616                                         {
1617                                                 RT_SET_ASIC_WCID        SetAsicWcid;
1618                                                 USHORT          offset;
1619                                                 UINT32          MACValue, MACRValue = 0;
1620                                                 SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
1621
1622                                                 if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
1623                                                         return;
1624
1625                                                 offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
1626
1627                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
1628                                                 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]);
1629                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
1630                                                 RTUSBWriteMACRegister(pAd, offset, MACValue);
1631                                                 // Read bitmask
1632                                                 RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
1633                                                 if ( SetAsicWcid.DeleteTid != 0xffffffff)
1634                                                         MACRValue &= (~SetAsicWcid.DeleteTid);
1635                                                 if (SetAsicWcid.SetTid != 0xffffffff)
1636                                                         MACRValue |= (SetAsicWcid.SetTid);
1637                                                 MACRValue &= 0xffff0000;
1638
1639                                                 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
1640                                                 MACValue |= MACRValue;
1641                                                 RTUSBWriteMACRegister(pAd, offset+4, MACValue);
1642
1643                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
1644                                         }
1645                                         break;
1646
1647                                 case CMDTHREAD_SET_ASIC_WCID_CIPHER:
1648                                         {
1649 #ifdef CONFIG_STA_SUPPORT
1650                                                 RT_SET_ASIC_WCID_ATTRI  SetAsicWcidAttri;
1651                                                 USHORT          offset;
1652                                                 UINT32          MACRValue = 0;
1653                                                 SHAREDKEY_MODE_STRUC csr1;
1654                                                 SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
1655
1656                                                 if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
1657                                                         return;
1658
1659                                                 offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
1660
1661                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
1662                                                 // Read bitmask
1663                                                 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1664                                                 MACRValue = 0;
1665                                                 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1666
1667                                                 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1668                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1669
1670                                                 offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
1671                                                 MACRValue = 0;
1672                                                 if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
1673                                                         MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
1674                                                 else
1675                                                         MACRValue |= (0x20000000);
1676                                                 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1677                                                 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1678
1679                                                 //
1680                                                 // Update cipher algorithm. WSTA always use BSS0
1681                                                 //
1682                                                 // for adhoc mode only ,because wep status slow than add key, when use zero config
1683                                                 if (pAd->StaCfg.BssType == BSS_ADHOC )
1684                                                 {
1685                                                         offset = MAC_WCID_ATTRIBUTE_BASE;
1686
1687                                                         RTUSBReadMACRegister(pAd, offset, &MACRValue);
1688                                                         MACRValue &= (~0xe);
1689                                                         MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1690
1691                                                         RTUSBWriteMACRegister(pAd, offset, MACRValue);
1692
1693                                                         //Update group key cipher,,because wep status slow than add key, when use zero config
1694                                                         RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
1695
1696                                                         csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
1697                                                         csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
1698
1699                                                         RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
1700                                                 }
1701 #endif // CONFIG_STA_SUPPORT //
1702                                         }
1703                                         break;
1704
1705 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1706                                 case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
1707                                 {
1708                                         RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1709                                         KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
1710                                         AsicAddPairwiseKeyEntry(pAd,
1711                                                                                         KeyInfo.MacAddr,
1712                                                                                         (UCHAR)KeyInfo.MacTabMatchWCID,
1713                                                                                         &KeyInfo.CipherKey);
1714                                 }
1715                                         break;
1716                                 case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
1717                                 {
1718                                         PMAC_TABLE_ENTRY pEntry;
1719                                         UCHAR KeyIdx;
1720                                         UCHAR CipherAlg;
1721                                         UCHAR ApIdx;
1722
1723                                         pEntry = (PMAC_TABLE_ENTRY)(pData);
1724
1725 #ifdef CONFIG_STA_SUPPORT
1726 #ifdef QOS_DLS_SUPPORT
1727                                         KeyIdx = 0;
1728                                         CipherAlg = pEntry->PairwiseKey.CipherAlg;
1729                                         ApIdx = BSS0;
1730 #endif // QOS_DLS_SUPPORT //
1731 #endif // CONFIG_STA_SUPPORT //
1732
1733
1734                                                 RTMPAddWcidAttributeEntry(
1735                                                                                   pAd,
1736                                                                                   ApIdx,
1737                                                                                   KeyIdx,
1738                                                                                   CipherAlg,
1739                                                                                   pEntry);
1740                                         }
1741                                                 break;
1742 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1743
1744                                 case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
1745                                         {
1746                                                 MAC_TABLE_ENTRY *pEntry;
1747                                                 pEntry = (MAC_TABLE_ENTRY *)pData;
1748
1749
1750 #ifdef CONFIG_STA_SUPPORT
1751                                                 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1752                                                 {
1753                                                         AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
1754                                                         if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
1755                                                         {
1756                                                                 UINT32 uIV = 0;
1757                                                                 PUCHAR  ptr;
1758
1759                                                                 ptr = (PUCHAR) &uIV;
1760                                                                 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1761                                                                 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1762                                                                 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1763                                                         }
1764                                                         else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
1765                                                         {
1766                                                                 UINT32 uIV = 0;
1767                                                                 PUCHAR  ptr;
1768
1769                                                                 ptr = (PUCHAR) &uIV;
1770                                                                 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1771                                                                 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1772                                                                 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1773                                                         }
1774                                                         else
1775                                                         {
1776                                                                 //
1777                                                                 // Other case, disable engine.
1778                                                                 // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
1779                                                                 //
1780                                                                 USHORT   offset;
1781                                                                 offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
1782                                                                 // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
1783                                                                 RTUSBWriteMACRegister(pAd, offset, 0);
1784                                                         }
1785                                                 }
1786 #endif // CONFIG_STA_SUPPORT //
1787
1788                                                 AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
1789                                                 printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
1790                                                                 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
1791                                         }
1792                                         break;
1793
1794 // add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
1795                                 case CMDTHREAD_UPDATE_PROTECT:
1796                                         {
1797                                                 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
1798                                         }
1799                                         break;
1800 // end johnli
1801
1802                                 case OID_802_11_ADD_WEP:
1803                                         {
1804 #ifdef CONFIG_STA_SUPPORT
1805                                                 UINT    i;
1806                                                 UINT32  KeyIdx;
1807                                                 PNDIS_802_11_WEP        pWepKey;
1808
1809                                                 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP  \n"));
1810
1811                                                 pWepKey = (PNDIS_802_11_WEP)pData;
1812                                                 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
1813
1814                                                 // it is a shared key
1815                                                 if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
1816                                                 {
1817                                                         NdisStatus = NDIS_STATUS_INVALID_DATA;
1818                                                         DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
1819                                                 }
1820                                                 else
1821                                                 {
1822                                                         UCHAR CipherAlg;
1823                                                         pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
1824                                                         NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
1825                                                         CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
1826
1827                                                         //
1828                                                         // Change the WEP cipher to CKIP cipher if CKIP KP on.
1829                                                         // Funk UI or Meetinghouse UI will add ckip key from this path.
1830                                                         //
1831
1832                                                         if (pAd->OpMode == OPMODE_STA)
1833                                                         {
1834                                                                 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1835                                                                 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1836                                                         }
1837                                                         pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
1838                                                         if (pWepKey->KeyIndex & 0x80000000)
1839                                                         {
1840                                                                 // Default key for tx (shared key)
1841                                                                 UCHAR   IVEIV[8];
1842                                                                 UINT32  WCIDAttri, Value;
1843                                                                 USHORT  offset, offset2;
1844                                                                 NdisZeroMemory(IVEIV, 8);
1845                                                                 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
1846                                                                 // Add BSSID to WCTable. because this is Tx wep key.
1847                                                                 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
1848                                                                 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
1849
1850                                                                 offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
1851                                                                 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1852                                                                 // 1. IV/EIV
1853                                                                 // Specify key index to find shared key.
1854                                                                 IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
1855                                                                 offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1856                                                                 offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
1857                                                                 for (i=0; i<8;)
1858                                                                 {
1859                                                                         Value = IVEIV[i];
1860                                                                         Value += (IVEIV[i+1]<<8);
1861                                                                         Value += (IVEIV[i+2]<<16);
1862                                                                         Value += (IVEIV[i+3]<<24);
1863                                                                         RTUSBWriteMACRegister(pAd, offset+i, Value);
1864                                                                         RTUSBWriteMACRegister(pAd, offset2+i, Value);
1865                                                                         i+=4;
1866                                                                 }
1867
1868                                                                 // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1869                                                                 WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
1870                                                                 offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1871                                                                 DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
1872                                                                 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1873
1874                                                         }
1875                                                         AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
1876                                                         DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
1877                                                 }
1878 #endif // CONFIG_STA_SUPPORT //
1879                                         }
1880                                         break;
1881
1882                                 case CMDTHREAD_802_11_COUNTER_MEASURE:
1883                                         break;
1884
1885                                 default:
1886                                         DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
1887                                         break;
1888                         }
1889                 }
1890
1891                 if (cmdqelmt->CmdFromNdis == TRUE)
1892                 {
1893                                 if (cmdqelmt->buffer != NULL)
1894                                         NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1895
1896                         NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1897                 }
1898                 else
1899                 {
1900                         if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
1901                                 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1902             {
1903                                 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1904                         }
1905                 }
1906         }       /* end of while */
1907 }
1908