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