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