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