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