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