Staging: rt2870: Revert d44ca7 Removal of kernel_thread() API
[linux-2.6/mini2440.git] / drivers / staging / rt2870 / common / rtusb_io.c
blob704b5c2d5091a1327492f509c16e2b4d4a798075
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
27 Module Name:
28 rtusb_io.c
30 Abstract:
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 06-25-2004 created
39 #include "../rt_config.h"
43 ========================================================================
45 Routine Description: NIC initialization complete
47 Arguments:
49 Return Value:
51 IRQL =
53 Note:
55 ========================================================================
58 NTSTATUS RTUSBFirmwareRun(
59 IN PRTMP_ADAPTER pAd)
61 NTSTATUS Status;
63 Status = RTUSB_VendorRequest(
64 pAd,
65 USBD_TRANSFER_DIRECTION_OUT,
66 DEVICE_VENDOR_REQUEST_OUT,
67 0x01,
68 0x8,
70 NULL,
71 0);
73 return Status;
79 ========================================================================
81 Routine Description: Write Firmware to NIC.
83 Arguments:
85 Return Value:
87 IRQL =
89 Note:
91 ========================================================================
93 NTSTATUS RTUSBFirmwareWrite(
94 IN PRTMP_ADAPTER pAd,
95 IN PUCHAR pFwImage,
96 IN ULONG FwLen)
98 UINT32 MacReg;
99 NTSTATUS Status;
100 // ULONG i;
101 USHORT writeLen;
103 Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
106 writeLen = FwLen;
107 RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
109 Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
110 Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
111 Status = RTUSBFirmwareRun(pAd);
113 #ifdef RT30xx
114 RTMPusecDelay(10000);
115 RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
116 AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
117 #endif
119 return Status;
124 ========================================================================
126 Routine Description: Get current firmware operation mode (Return Value)
128 Arguments:
130 Return Value:
131 0 or 1 = Downloaded by host driver
132 others = Driver doesn't download firmware
134 IRQL =
136 Note:
138 ========================================================================
140 NTSTATUS RTUSBFirmwareOpmode(
141 IN PRTMP_ADAPTER pAd,
142 OUT PUINT32 pValue)
144 NTSTATUS Status;
146 Status = RTUSB_VendorRequest(
147 pAd,
148 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
149 DEVICE_VENDOR_REQUEST_IN,
150 0x1,
151 0x11,
153 pValue,
155 return Status;
157 NTSTATUS RTUSBVenderReset(
158 IN PRTMP_ADAPTER pAd)
160 NTSTATUS Status;
161 DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
162 Status = RTUSB_VendorRequest(
163 pAd,
164 USBD_TRANSFER_DIRECTION_OUT,
165 DEVICE_VENDOR_REQUEST_OUT,
166 0x01,
167 0x1,
169 NULL,
172 DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
173 return Status;
176 ========================================================================
178 Routine Description: Read various length data from RT2573
180 Arguments:
182 Return Value:
184 IRQL =
186 Note:
188 ========================================================================
190 NTSTATUS RTUSBMultiRead(
191 IN PRTMP_ADAPTER pAd,
192 IN USHORT Offset,
193 OUT PUCHAR pData,
194 IN USHORT length)
196 NTSTATUS Status;
198 Status = RTUSB_VendorRequest(
199 pAd,
200 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
201 DEVICE_VENDOR_REQUEST_IN,
202 0x7,
204 Offset,
205 pData,
206 length);
208 return Status;
212 ========================================================================
214 Routine Description: Write various length data to RT2573
216 Arguments:
218 Return Value:
220 IRQL =
222 Note:
224 ========================================================================
226 NTSTATUS RTUSBMultiWrite_OneByte(
227 IN PRTMP_ADAPTER pAd,
228 IN USHORT Offset,
229 IN PUCHAR pData)
231 NTSTATUS Status;
233 // TODO: In 2870, use this funciton carefully cause it's not stable.
234 Status = RTUSB_VendorRequest(
235 pAd,
236 USBD_TRANSFER_DIRECTION_OUT,
237 DEVICE_VENDOR_REQUEST_OUT,
238 0x6,
240 Offset,
241 pData,
244 return Status;
247 NTSTATUS RTUSBMultiWrite(
248 IN PRTMP_ADAPTER pAd,
249 IN USHORT Offset,
250 IN PUCHAR pData,
251 IN USHORT length)
253 NTSTATUS Status;
256 USHORT index = 0,Value;
257 PUCHAR pSrc = pData;
258 USHORT resude = 0;
260 resude = length % 2;
261 length += resude;
264 Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8));
265 Status = RTUSBSingleWrite(pAd,Offset + index,Value);
266 index +=2;
267 length -= 2;
268 pSrc = pSrc + 2;
269 }while(length > 0);
271 return Status;
275 NTSTATUS RTUSBSingleWrite(
276 IN RTMP_ADAPTER *pAd,
277 IN USHORT Offset,
278 IN USHORT Value)
280 NTSTATUS Status;
282 Status = RTUSB_VendorRequest(
283 pAd,
284 USBD_TRANSFER_DIRECTION_OUT,
285 DEVICE_VENDOR_REQUEST_OUT,
286 0x2,
287 Value,
288 Offset,
289 NULL,
292 return Status;
298 ========================================================================
300 Routine Description: Read 32-bit MAC register
302 Arguments:
304 Return Value:
306 IRQL =
308 Note:
310 ========================================================================
312 NTSTATUS RTUSBReadMACRegister(
313 IN PRTMP_ADAPTER pAd,
314 IN USHORT Offset,
315 OUT PUINT32 pValue)
317 NTSTATUS Status;
318 UINT32 localVal;
320 Status = RTUSB_VendorRequest(
321 pAd,
322 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
323 DEVICE_VENDOR_REQUEST_IN,
324 0x7,
326 Offset,
327 &localVal,
330 *pValue = le2cpu32(localVal);
333 if (Status < 0)
334 *pValue = 0xffffffff;
336 return Status;
341 ========================================================================
343 Routine Description: Write 32-bit MAC register
345 Arguments:
347 Return Value:
349 IRQL =
351 Note:
353 ========================================================================
355 NTSTATUS RTUSBWriteMACRegister(
356 IN PRTMP_ADAPTER pAd,
357 IN USHORT Offset,
358 IN UINT32 Value)
360 NTSTATUS Status;
361 UINT32 localVal;
363 localVal = Value;
365 Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
366 Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
368 return Status;
373 #if 1
375 ========================================================================
377 Routine Description: Read 8-bit BBP register
379 Arguments:
381 Return Value:
383 IRQL =
385 Note:
387 ========================================================================
389 NTSTATUS RTUSBReadBBPRegister(
390 IN PRTMP_ADAPTER pAd,
391 IN UCHAR Id,
392 IN PUCHAR pValue)
394 BBP_CSR_CFG_STRUC BbpCsr;
395 UINT i = 0;
396 NTSTATUS status;
398 // Verify the busy condition
401 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
402 if(status >= 0)
404 if (!(BbpCsr.field.Busy == BUSY))
405 break;
407 printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
408 i++;
410 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
412 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
415 // Read failed then Return Default value.
417 *pValue = pAd->BbpWriteLatch[Id];
419 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
420 return STATUS_UNSUCCESSFUL;
423 // Prepare for write material
424 BbpCsr.word = 0;
425 BbpCsr.field.fRead = 1;
426 BbpCsr.field.Busy = 1;
427 BbpCsr.field.RegNum = Id;
428 RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
430 i = 0;
431 // Verify the busy condition
434 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
435 if (status >= 0)
437 if (!(BbpCsr.field.Busy == BUSY))
439 *pValue = (UCHAR)BbpCsr.field.Value;
440 break;
443 printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
444 i++;
446 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
448 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
451 // Read failed then Return Default value.
453 *pValue = pAd->BbpWriteLatch[Id];
455 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
456 return STATUS_UNSUCCESSFUL;
459 return STATUS_SUCCESS;
461 #else
463 ========================================================================
465 Routine Description: Read 8-bit BBP register via firmware
467 Arguments:
469 Return Value:
471 IRQL =
473 Note:
475 ========================================================================
477 NTSTATUS RTUSBReadBBPRegister(
478 IN PRTMP_ADAPTER pAd,
479 IN UCHAR Id,
480 IN PUCHAR pValue)
482 BBP_CSR_CFG_STRUC BbpCsr;
483 int i, k;
484 for (i=0; i<MAX_BUSY_COUNT; i++)
486 RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
487 if (BbpCsr.field.Busy == BUSY)
489 continue;
491 BbpCsr.word = 0;
492 BbpCsr.field.fRead = 1;
493 BbpCsr.field.BBP_RW_MODE = 1;
494 BbpCsr.field.Busy = 1;
495 BbpCsr.field.RegNum = Id;
496 RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
497 AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
498 for (k=0; k<MAX_BUSY_COUNT; k++)
500 RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
501 if (BbpCsr.field.Busy == IDLE)
502 break;
504 if ((BbpCsr.field.Busy == IDLE) &&
505 (BbpCsr.field.RegNum == Id))
507 *pValue = (UCHAR)BbpCsr.field.Value;
508 break;
511 if (BbpCsr.field.Busy == BUSY)
513 DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
514 *pValue = pAd->BbpWriteLatch[Id];
515 return STATUS_UNSUCCESSFUL;
517 return STATUS_SUCCESS;
519 #endif
521 #if 1
523 ========================================================================
525 Routine Description: Write 8-bit BBP register
527 Arguments:
529 Return Value:
531 IRQL =
533 Note:
535 ========================================================================
537 NTSTATUS RTUSBWriteBBPRegister(
538 IN PRTMP_ADAPTER pAd,
539 IN UCHAR Id,
540 IN UCHAR Value)
542 BBP_CSR_CFG_STRUC BbpCsr;
543 UINT i = 0;
544 NTSTATUS status;
545 // Verify the busy condition
548 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
549 if (status >= 0)
551 if (!(BbpCsr.field.Busy == BUSY))
552 break;
554 printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
555 i++;
557 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
559 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
561 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
562 return STATUS_UNSUCCESSFUL;
565 // Prepare for write material
566 BbpCsr.word = 0;
567 BbpCsr.field.fRead = 0;
568 BbpCsr.field.Value = Value;
569 BbpCsr.field.Busy = 1;
570 BbpCsr.field.RegNum = Id;
571 RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
573 pAd->BbpWriteLatch[Id] = Value;
575 return STATUS_SUCCESS;
577 #else
579 ========================================================================
581 Routine Description: Write 8-bit BBP register via firmware
583 Arguments:
585 Return Value:
587 IRQL =
589 Note:
591 ========================================================================
594 NTSTATUS RTUSBWriteBBPRegister(
595 IN PRTMP_ADAPTER pAd,
596 IN UCHAR Id,
597 IN UCHAR Value)
600 BBP_CSR_CFG_STRUC BbpCsr;
601 int BusyCnt;
602 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
604 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
605 if (BbpCsr.field.Busy == BUSY)
606 continue;
607 BbpCsr.word = 0;
608 BbpCsr.field.fRead = 0;
609 BbpCsr.field.BBP_RW_MODE = 1;
610 BbpCsr.field.Busy = 1;
611 BbpCsr.field.Value = Value;
612 BbpCsr.field.RegNum = Id;
613 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
614 AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
615 pAd->BbpWriteLatch[Id] = Value;
616 break;
618 if (BusyCnt == MAX_BUSY_COUNT)
620 DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
621 return STATUS_UNSUCCESSFUL;
623 return STATUS_SUCCESS;
625 #endif
627 ========================================================================
629 Routine Description: Write RF register through MAC
631 Arguments:
633 Return Value:
635 IRQL =
637 Note:
639 ========================================================================
641 NTSTATUS RTUSBWriteRFRegister(
642 IN PRTMP_ADAPTER pAd,
643 IN UINT32 Value)
645 PHY_CSR4_STRUC PhyCsr4;
646 UINT i = 0;
647 NTSTATUS status;
649 NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
652 status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
653 if (status >= 0)
655 if (!(PhyCsr4.field.Busy))
656 break;
658 printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
659 i++;
661 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
663 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
665 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
666 return STATUS_UNSUCCESSFUL;
669 RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
671 return STATUS_SUCCESS;
674 #ifndef RT30xx
676 ========================================================================
678 Routine Description: Write RT3070 RF register through MAC
680 Arguments:
682 Return Value:
684 IRQL =
686 Note:
688 ========================================================================
690 NTSTATUS RT30xxWriteRFRegister(
691 IN PRTMP_ADAPTER pAd,
692 IN UCHAR RegID,
693 IN UCHAR Value)
695 RF_CSR_CFG_STRUC rfcsr;
696 UINT i = 0;
700 RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
702 if (!rfcsr.field.RF_CSR_KICK)
703 break;
704 i++;
706 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
708 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
710 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
711 return STATUS_UNSUCCESSFUL;
714 rfcsr.field.RF_CSR_WR = 1;
715 rfcsr.field.RF_CSR_KICK = 1;
716 rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
717 rfcsr.field.RF_CSR_DATA = Value;
719 RTUSBWriteMACRegister(pAd, RF_CSR_CFG, rfcsr.word);
721 return STATUS_SUCCESS;
725 ========================================================================
727 Routine Description: Read RT3070 RF register through MAC
729 Arguments:
731 Return Value:
733 IRQL =
735 Note:
737 ========================================================================
739 NTSTATUS RT30xxReadRFRegister(
740 IN PRTMP_ADAPTER pAd,
741 IN UCHAR RegID,
742 IN PUCHAR pValue)
744 RF_CSR_CFG_STRUC rfcsr;
745 UINT i=0, k;
747 for (i=0; i<MAX_BUSY_COUNT; i++)
749 RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
751 if (rfcsr.field.RF_CSR_KICK == BUSY)
753 continue;
755 rfcsr.word = 0;
756 rfcsr.field.RF_CSR_WR = 0;
757 rfcsr.field.RF_CSR_KICK = 1;
758 rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
759 RTUSBWriteMACRegister(pAd, RF_CSR_CFG, rfcsr.word);
760 for (k=0; k<MAX_BUSY_COUNT; k++)
762 RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
764 if (rfcsr.field.RF_CSR_KICK == IDLE)
765 break;
767 if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
768 (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
770 *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
771 break;
774 if (rfcsr.field.RF_CSR_KICK == BUSY)
776 DBGPRINT_ERR(("RF read R%d=0x%x fail\n", RegID, rfcsr.word));
777 return STATUS_UNSUCCESSFUL;
780 return STATUS_SUCCESS;
782 #endif /* RT30xx */
785 ========================================================================
787 Routine Description:
789 Arguments:
791 Return Value:
793 IRQL =
795 Note:
797 ========================================================================
799 NTSTATUS RTUSBReadEEPROM(
800 IN PRTMP_ADAPTER pAd,
801 IN USHORT Offset,
802 OUT PUCHAR pData,
803 IN USHORT length)
805 NTSTATUS Status = STATUS_SUCCESS;
807 #ifdef RT30xx
808 if(pAd->bUseEfuse)
810 Status =eFuseRead(pAd, Offset, pData, length);
812 else
813 #endif // RT30xx //
815 Status = RTUSB_VendorRequest(
816 pAd,
817 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
818 DEVICE_VENDOR_REQUEST_IN,
819 0x9,
821 Offset,
822 pData,
823 length);
826 return Status;
830 ========================================================================
832 Routine Description:
834 Arguments:
836 Return Value:
838 IRQL =
840 Note:
842 ========================================================================
844 NTSTATUS RTUSBWriteEEPROM(
845 IN PRTMP_ADAPTER pAd,
846 IN USHORT Offset,
847 IN PUCHAR pData,
848 IN USHORT length)
850 NTSTATUS Status = STATUS_SUCCESS;
852 #ifdef RT30xx
853 if(pAd->bUseEfuse)
855 Status = eFuseWrite(pAd, Offset, pData, length);
857 else
858 #endif // RT30xx //
860 Status = RTUSB_VendorRequest(
861 pAd,
862 USBD_TRANSFER_DIRECTION_OUT,
863 DEVICE_VENDOR_REQUEST_OUT,
864 0x8,
866 Offset,
867 pData,
868 length);
871 return Status;
875 ========================================================================
877 Routine Description:
879 Arguments:
881 Return Value:
883 IRQL =
885 Note:
887 ========================================================================
889 VOID RTUSBPutToSleep(
890 IN PRTMP_ADAPTER pAd)
892 UINT32 value;
894 // Timeout 0x40 x 50us
895 value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
896 RTUSBWriteMACRegister(pAd, 0x7010, value);
897 RTUSBWriteMACRegister(pAd, 0x404, 0x30);
898 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
899 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
904 ========================================================================
906 Routine Description:
908 Arguments:
910 Return Value:
912 IRQL =
914 Note:
916 ========================================================================
918 NTSTATUS RTUSBWakeUp(
919 IN PRTMP_ADAPTER pAd)
921 NTSTATUS Status;
923 Status = RTUSB_VendorRequest(
924 pAd,
925 USBD_TRANSFER_DIRECTION_OUT,
926 DEVICE_VENDOR_REQUEST_OUT,
927 0x01,
928 0x09,
930 NULL,
933 return Status;
937 ========================================================================
939 Routine Description:
941 Arguments:
943 Return Value:
945 IRQL =
947 Note:
949 ========================================================================
951 VOID RTUSBInitializeCmdQ(
952 IN PCmdQ cmdq)
954 cmdq->head = NULL;
955 cmdq->tail = NULL;
956 cmdq->size = 0;
957 cmdq->CmdQState = RT2870_THREAD_INITED;
961 ========================================================================
963 Routine Description:
965 Arguments:
967 Return Value:
969 IRQL =
971 Note:
973 ========================================================================
975 NDIS_STATUS RTUSBEnqueueCmdFromNdis(
976 IN PRTMP_ADAPTER pAd,
977 IN NDIS_OID Oid,
978 IN BOOLEAN SetInformation,
979 IN PVOID pInformationBuffer,
980 IN UINT32 InformationBufferLength)
982 NDIS_STATUS status;
983 PCmdQElmt cmdqelmt = NULL;
984 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
986 #ifndef RT30xx
987 CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
988 #endif
989 #ifdef RT30xx
990 if (pObj->RTUSBCmdThr_pid < 0)
991 #endif
992 return (NDIS_STATUS_RESOURCES);
994 status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
995 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
996 return (NDIS_STATUS_RESOURCES);
998 cmdqelmt->buffer = NULL;
999 if (pInformationBuffer != NULL)
1001 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
1002 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
1004 kfree(cmdqelmt);
1005 return (NDIS_STATUS_RESOURCES);
1007 else
1009 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
1010 cmdqelmt->bufferlength = InformationBufferLength;
1013 else
1014 cmdqelmt->bufferlength = 0;
1016 cmdqelmt->command = Oid;
1017 cmdqelmt->CmdFromNdis = TRUE;
1018 if (SetInformation == TRUE)
1019 cmdqelmt->SetOperation = TRUE;
1020 else
1021 cmdqelmt->SetOperation = FALSE;
1023 NdisAcquireSpinLock(&pAd->CmdQLock);
1024 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
1026 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
1027 status = NDIS_STATUS_SUCCESS;
1029 else
1031 status = NDIS_STATUS_FAILURE;
1033 NdisReleaseSpinLock(&pAd->CmdQLock);
1035 if (status == NDIS_STATUS_FAILURE)
1037 if (cmdqelmt->buffer)
1038 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1039 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1041 else
1042 RTUSBCMDUp(pAd);
1045 return(NDIS_STATUS_SUCCESS);
1049 ========================================================================
1051 Routine Description:
1053 Arguments:
1055 Return Value:
1057 IRQL =
1059 Note:
1061 ========================================================================
1063 NDIS_STATUS RTUSBEnqueueInternalCmd(
1064 IN PRTMP_ADAPTER pAd,
1065 IN NDIS_OID Oid,
1066 IN PVOID pInformationBuffer,
1067 IN UINT32 InformationBufferLength)
1069 NDIS_STATUS status;
1070 PCmdQElmt cmdqelmt = NULL;
1073 status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
1074 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
1075 return (NDIS_STATUS_RESOURCES);
1076 NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
1078 if(InformationBufferLength > 0)
1080 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
1081 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
1083 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1084 return (NDIS_STATUS_RESOURCES);
1086 else
1088 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
1089 cmdqelmt->bufferlength = InformationBufferLength;
1092 else
1094 cmdqelmt->buffer = NULL;
1095 cmdqelmt->bufferlength = 0;
1098 cmdqelmt->command = Oid;
1099 cmdqelmt->CmdFromNdis = FALSE;
1101 if (cmdqelmt != NULL)
1103 NdisAcquireSpinLock(&pAd->CmdQLock);
1104 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
1106 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
1107 status = NDIS_STATUS_SUCCESS;
1109 else
1111 status = NDIS_STATUS_FAILURE;
1113 NdisReleaseSpinLock(&pAd->CmdQLock);
1115 if (status == NDIS_STATUS_FAILURE)
1117 if (cmdqelmt->buffer)
1118 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1119 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1121 else
1122 RTUSBCMDUp(pAd);
1124 return(NDIS_STATUS_SUCCESS);
1128 ========================================================================
1130 Routine Description:
1132 Arguments:
1134 Return Value:
1136 IRQL =
1138 Note:
1140 ========================================================================
1142 VOID RTUSBDequeueCmd(
1143 IN PCmdQ cmdq,
1144 OUT PCmdQElmt *pcmdqelmt)
1146 *pcmdqelmt = cmdq->head;
1148 if (*pcmdqelmt != NULL)
1150 cmdq->head = cmdq->head->next;
1151 cmdq->size--;
1152 if (cmdq->size == 0)
1153 cmdq->tail = NULL;
1158 ========================================================================
1159 usb_control_msg - Builds a control urb, sends it off and waits for completion
1160 @dev: pointer to the usb device to send the message to
1161 @pipe: endpoint "pipe" to send the message to
1162 @request: USB message request value
1163 @requesttype: USB message request type value
1164 @value: USB message value
1165 @index: USB message index value
1166 @data: pointer to the data to send
1167 @size: length in bytes of the data to send
1168 @timeout: time in jiffies to wait for the message to complete before
1169 timing out (if 0 the wait is forever)
1170 Context: !in_interrupt ()
1172 This function sends a simple control message to a specified endpoint
1173 and waits for the message to complete, or timeout.
1174 If successful, it returns the number of bytes transferred, otherwise a negative error number.
1176 Don't use this function from within an interrupt context, like a
1177 bottom half handler. If you need an asynchronous message, or need to send
1178 a message from within interrupt context, use usb_submit_urb()
1179 If a thread in your driver uses this call, make sure your disconnect()
1180 method can wait for it to complete. Since you don't have a handle on
1181 the URB used, you can't cancel the request.
1184 Routine Description:
1186 Arguments:
1188 Return Value:
1190 Note:
1192 ========================================================================
1194 NTSTATUS RTUSB_VendorRequest(
1195 IN PRTMP_ADAPTER pAd,
1196 IN UINT32 TransferFlags,
1197 IN UCHAR RequestType,
1198 IN UCHAR Request,
1199 IN USHORT Value,
1200 IN USHORT Index,
1201 IN PVOID TransferBuffer,
1202 IN UINT32 TransferBufferLength)
1204 int ret;
1205 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1207 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1209 DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
1210 return -1;
1212 else if (in_interrupt())
1214 DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
1216 return -1;
1218 else
1220 #define MAX_RETRY_COUNT 10
1222 int retryCount = 0;
1223 void *tmpBuf = TransferBuffer;
1225 // Acquire Control token
1226 do {
1227 if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1228 ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1229 else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1230 ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1231 else
1233 DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
1234 ret = -1;
1237 retryCount++;
1238 if (ret < 0) {
1239 printk("#\n");
1240 RTMPusecDelay(5000);
1242 } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
1244 if (ret < 0) {
1245 // DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
1246 DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
1247 ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
1248 if (Request == 0x2)
1249 DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
1251 if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
1252 hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
1255 return ret;
1259 ========================================================================
1261 Routine Description:
1262 Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
1263 synchronously. Callers of this function must be running at
1264 PASSIVE LEVEL.
1266 Arguments:
1268 Return Value:
1270 Note:
1272 ========================================================================
1274 NTSTATUS RTUSB_ResetDevice(
1275 IN PRTMP_ADAPTER pAd)
1277 NTSTATUS Status = TRUE;
1279 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
1280 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
1281 return Status;
1284 VOID CMDHandler(
1285 IN PRTMP_ADAPTER pAd)
1287 PCmdQElmt cmdqelmt;
1288 PUCHAR pData;
1289 NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
1290 // ULONG Now = 0;
1291 NTSTATUS ntStatus;
1292 // unsigned long IrqFlags;
1294 while (pAd->CmdQ.size > 0)
1296 NdisStatus = NDIS_STATUS_SUCCESS;
1298 NdisAcquireSpinLock(&pAd->CmdQLock);
1299 RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
1300 NdisReleaseSpinLock(&pAd->CmdQLock);
1302 if (cmdqelmt == NULL)
1303 break;
1305 pData = cmdqelmt->buffer;
1307 if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1309 switch (cmdqelmt->command)
1311 case CMDTHREAD_CHECK_GPIO:
1313 UINT32 data;
1316 // Read GPIO pin2 as Hardware controlled radio state
1318 RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
1320 if (data & 0x04)
1322 pAd->StaCfg.bHwRadio = TRUE;
1324 else
1326 pAd->StaCfg.bHwRadio = FALSE;
1329 if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1331 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1332 if(pAd->StaCfg.bRadio == TRUE)
1334 DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
1336 MlmeRadioOn(pAd);
1337 // Update extra information
1338 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1340 else
1342 DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
1344 MlmeRadioOff(pAd);
1345 // Update extra information
1346 pAd->ExtraInfo = HW_RADIO_OFF;
1351 break;
1353 case CMDTHREAD_QKERIODIC_EXECUT:
1355 StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
1357 break;
1359 case CMDTHREAD_RESET_BULK_OUT:
1361 UINT32 MACValue;
1362 UCHAR Index;
1363 int ret=0;
1364 PHT_TX_CONTEXT pHTTXContext;
1365 // RTMP_TX_RING *pTxRing;
1366 unsigned long IrqFlags;
1368 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
1369 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1370 //RTUSBCancelPendingBulkOutIRP(pAd);
1371 // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
1372 Index = 0;
1375 RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
1376 if ((MACValue & 0xf00000/*0x800000*/) == 0)
1377 break;
1378 Index++;
1379 RTMPusecDelay(10000);
1380 }while(Index < 100);
1381 MACValue = 0;
1382 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1383 // To prevent Read Register error, we 2nd check the validity.
1384 if ((MACValue & 0xc00000) == 0)
1385 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1386 // To prevent Read Register error, we 3rd check the validity.
1387 if ((MACValue & 0xc00000) == 0)
1388 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1389 MACValue |= 0x80000;
1390 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1392 // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1393 RTMPusecDelay(1000);
1395 MACValue &= (~0x80000);
1396 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1397 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
1399 // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1400 //RTMPusecDelay(5000);
1402 if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
1404 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1405 if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1407 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1409 RTUSBKickBulkOut(pAd);
1411 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
1413 else
1415 pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
1416 //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1417 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1418 if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
1420 pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
1421 pHTTXContext->IRPPending = TRUE;
1422 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
1424 // no matter what, clean the flag
1425 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1427 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1428 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1429 /*-----------------------------------------------------------------------------------------------*/
1430 /*-----------------------------------------------------------------------------------------------*/
1432 RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
1434 if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
1436 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1437 pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
1438 pHTTXContext->IRPPending = FALSE;
1439 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
1440 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1442 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
1444 else
1446 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1447 DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
1448 pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
1449 pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
1450 DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
1451 pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1452 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1453 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
1458 else
1460 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1461 //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1463 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
1464 if (pAd->bulkResetPipeid == 0)
1466 UCHAR pendingContext = 0;
1467 PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
1468 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
1469 PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
1470 PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
1472 if (pHTTXContext->IRPPending)
1473 pendingContext |= 1;
1474 else if (pMLMEContext->IRPPending)
1475 pendingContext |= 2;
1476 else if (pNULLContext->IRPPending)
1477 pendingContext |= 4;
1478 else if (pPsPollContext->IRPPending)
1479 pendingContext |= 8;
1480 else
1481 pendingContext = 0;
1483 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
1486 // no matter what, clean the flag
1487 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1489 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1491 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
1494 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1495 //RTUSBKickBulkOut(pAd);
1500 // Don't cancel BULKIN.
1501 while ((atomic_read(&pAd->PendingRx) > 0) &&
1502 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1504 if (atomic_read(&pAd->PendingRx) > 0)
1506 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
1507 RTUSBCancelPendingBulkInIRP(pAd);
1509 RTMPusecDelay(100000);
1512 if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1514 UCHAR i;
1515 RTUSBRxPacket(pAd);
1516 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1517 pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
1518 for (i = 0; i < (RX_RING_SIZE); i++)
1520 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1522 pRxContext->pAd = pAd;
1523 pRxContext->InUse = FALSE;
1524 pRxContext->IRPPending = FALSE;
1525 pRxContext->Readable = FALSE;
1526 pRxContext->ReorderInUse = FALSE;
1529 RTUSBBulkReceive(pAd);
1530 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
1532 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
1533 break;
1535 case CMDTHREAD_RESET_BULK_IN:
1536 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
1538 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1540 UINT32 MACValue;
1541 /*-----------------------------------------------------------------------------------------------*/
1542 /*-----------------------------------------------------------------------------------------------*/
1544 //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1545 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1547 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
1548 RTUSBCancelPendingBulkInIRP(pAd);
1549 RTMPusecDelay(100000);
1550 pAd->PendingRx = 0;
1554 // Wait 10ms before reading register.
1555 RTMPusecDelay(10000);
1556 ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
1558 if ((NT_SUCCESS(ntStatus) == TRUE) &&
1559 (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1560 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
1562 UCHAR i;
1564 if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1565 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
1566 break;
1567 pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
1568 DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
1569 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
1570 for (i = 0; i < RX_RING_SIZE; i++)
1572 DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
1573 , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
1577 DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
1579 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1580 pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
1581 for (i = 0; i < (RX_RING_SIZE); i++)
1583 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1585 pRxContext->pAd = pAd;
1586 pRxContext->InUse = FALSE;
1587 pRxContext->IRPPending = FALSE;
1588 pRxContext->Readable = FALSE;
1589 pRxContext->ReorderInUse = FALSE;
1592 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1593 for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
1595 //RTUSBBulkReceive(pAd);
1596 PRX_CONTEXT pRxContext;
1597 PURB pUrb;
1598 int ret = 0;
1599 unsigned long IrqFlags;
1602 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1603 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1604 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1606 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1607 break;
1609 pRxContext->InUse = TRUE;
1610 pRxContext->IRPPending = TRUE;
1611 pAd->PendingRx++;
1612 pAd->BulkInReq++;
1613 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1615 // Init Rx context descriptor
1616 RTUSBInitRxDesc(pAd, pRxContext);
1617 pUrb = pRxContext->pUrb;
1618 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1619 { // fail
1621 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1622 pRxContext->InUse = FALSE;
1623 pRxContext->IRPPending = FALSE;
1624 pAd->PendingRx--;
1625 pAd->BulkInReq--;
1626 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1627 DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
1629 else
1630 { // success
1631 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
1632 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1637 else
1639 // Card must be removed
1640 if (NT_SUCCESS(ntStatus) != TRUE)
1642 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
1643 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
1645 else
1647 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
1651 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
1652 break;
1654 case CMDTHREAD_SET_ASIC_WCID:
1656 RT_SET_ASIC_WCID SetAsicWcid;
1657 USHORT offset;
1658 UINT32 MACValue, MACRValue = 0;
1659 SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
1661 if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
1662 return;
1664 offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
1666 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
1667 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
1668 DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
1669 RTUSBWriteMACRegister(pAd, offset, MACValue);
1670 // Read bitmask
1671 RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
1672 if ( SetAsicWcid.DeleteTid != 0xffffffff)
1673 MACRValue &= (~SetAsicWcid.DeleteTid);
1674 if (SetAsicWcid.SetTid != 0xffffffff)
1675 MACRValue |= (SetAsicWcid.SetTid);
1676 MACRValue &= 0xffff0000;
1678 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
1679 MACValue |= MACRValue;
1680 RTUSBWriteMACRegister(pAd, offset+4, MACValue);
1682 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
1684 break;
1686 case CMDTHREAD_SET_ASIC_WCID_CIPHER:
1688 RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri;
1689 USHORT offset;
1690 UINT32 MACRValue = 0;
1691 SHAREDKEY_MODE_STRUC csr1;
1692 SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
1694 if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
1695 return;
1697 offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
1699 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
1700 // Read bitmask
1701 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1702 MACRValue = 0;
1703 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1705 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1706 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1708 offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
1709 MACRValue = 0;
1710 if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
1711 MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
1712 else
1713 MACRValue |= (0x20000000);
1714 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1715 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1718 // Update cipher algorithm. WSTA always use BSS0
1720 // for adhoc mode only ,because wep status slow than add key, when use zero config
1721 if (pAd->StaCfg.BssType == BSS_ADHOC )
1723 offset = MAC_WCID_ATTRIBUTE_BASE;
1725 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1726 MACRValue &= (~0xe);
1727 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1729 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1731 //Update group key cipher,,because wep status slow than add key, when use zero config
1732 RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
1734 csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
1735 csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
1737 RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
1740 break;
1742 #ifdef RT30xx
1743 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
1744 case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
1746 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1747 KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
1748 AsicAddPairwiseKeyEntry(pAd,
1749 KeyInfo.MacAddr,
1750 (UCHAR)KeyInfo.MacTabMatchWCID,
1751 &KeyInfo.CipherKey);
1753 break;
1754 case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
1756 PMAC_TABLE_ENTRY pEntry;
1757 UCHAR KeyIdx;
1758 UCHAR CipherAlg;
1759 UCHAR ApIdx;
1761 pEntry = (PMAC_TABLE_ENTRY)(pData);
1763 RTMPAddWcidAttributeEntry(
1764 pAd,
1765 ApIdx,
1766 KeyIdx,
1767 CipherAlg,
1768 pEntry);
1770 break;
1771 //Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
1772 #endif
1774 case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
1776 MAC_TABLE_ENTRY *pEntry;
1777 pEntry = (MAC_TABLE_ENTRY *)pData;
1780 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
1781 if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
1783 UINT32 uIV = 0;
1784 PUCHAR ptr;
1786 ptr = (PUCHAR) &uIV;
1787 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1788 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1789 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1791 else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
1793 UINT32 uIV = 0;
1794 PUCHAR ptr;
1796 ptr = (PUCHAR) &uIV;
1797 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1798 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1799 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1801 else
1804 // Other case, disable engine.
1805 // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
1807 USHORT offset;
1808 offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
1809 // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
1810 RTUSBWriteMACRegister(pAd, offset, 0);
1814 AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
1815 printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
1816 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
1818 break;
1820 #ifdef RT30xx
1821 // add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
1822 case CMDTHREAD_UPDATE_PROTECT:
1824 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
1826 break;
1827 // end johnli
1828 #endif
1830 case OID_802_11_ADD_WEP:
1832 UINT i;
1833 UINT32 KeyIdx;
1834 PNDIS_802_11_WEP pWepKey;
1836 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP \n"));
1838 pWepKey = (PNDIS_802_11_WEP)pData;
1839 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
1841 // it is a shared key
1842 if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
1844 NdisStatus = NDIS_STATUS_INVALID_DATA;
1845 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
1847 else
1849 UCHAR CipherAlg;
1850 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
1851 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
1852 CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
1855 // Change the WEP cipher to CKIP cipher if CKIP KP on.
1856 // Funk UI or Meetinghouse UI will add ckip key from this path.
1859 if (pAd->OpMode == OPMODE_STA)
1861 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1862 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1864 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
1865 if (pWepKey->KeyIndex & 0x80000000)
1867 // Default key for tx (shared key)
1868 UCHAR IVEIV[8];
1869 UINT32 WCIDAttri, Value;
1870 USHORT offset, offset2;
1871 NdisZeroMemory(IVEIV, 8);
1872 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
1873 // Add BSSID to WCTable. because this is Tx wep key.
1874 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
1875 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
1877 offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
1878 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1879 // 1. IV/EIV
1880 // Specify key index to find shared key.
1881 IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
1882 offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1883 offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
1884 for (i=0; i<8;)
1886 Value = IVEIV[i];
1887 Value += (IVEIV[i+1]<<8);
1888 Value += (IVEIV[i+2]<<16);
1889 Value += (IVEIV[i+3]<<24);
1890 RTUSBWriteMACRegister(pAd, offset+i, Value);
1891 RTUSBWriteMACRegister(pAd, offset2+i, Value);
1892 i+=4;
1895 // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1896 WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
1897 offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1898 DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
1899 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1902 AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
1903 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
1906 break;
1908 case CMDTHREAD_802_11_COUNTER_MEASURE:
1909 break;
1910 default:
1911 DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
1912 break;
1916 if (cmdqelmt->CmdFromNdis == TRUE)
1918 if (cmdqelmt->buffer != NULL)
1919 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1921 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1923 else
1925 if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
1926 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1928 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1931 } /* end of while */