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