コード例 #1
0
ファイル: rtusb_io.c プロジェクト: vanhoefm/rt2870linux
VOID CMDHandler(                                                                                                                                                
    IN PRTMP_ADAPTER pAd)                                                                                                                                       
{                                                                                                                                                               
	PCmdQElmt		cmdqelmt;                                                                                                                                       
	PUCHAR			pData;                                                                                                                                          
	NDIS_STATUS		NdisStatus = NDIS_STATUS_SUCCESS;                                                                                                               
//	ULONG			Now = 0;
	NTSTATUS		ntStatus;
//	unsigned long	IrqFlags;
	
	while (pAd && pAd->CmdQ.size > 0)	
	{                                                                                                                                                           
		NdisStatus = NDIS_STATUS_SUCCESS;
		                                                                                                                      
		NdisAcquireSpinLock(&pAd->CmdQLock);
		RTThreadDequeueCmd(&pAd->CmdQ, &cmdqelmt);
		NdisReleaseSpinLock(&pAd->CmdQLock);
		                                                                                                        
		if (cmdqelmt == NULL)                                                                                                                                   
			break; 
			                                                                                                                                             
		pData = cmdqelmt->buffer;                                      
		                                                                                         
		if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
		{
			switch (cmdqelmt->command)
			{
				case CMDTHREAD_CHECK_GPIO:
					{
#ifdef CONFIG_STA_SUPPORT
						UINT32 data;
#endif // CONFIG_STA_SUPPORT //

#ifdef RALINK_ATE			
       					if(ATE_ON(pAd))
						{
							ATEDBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
							break;
						}	
#endif // RALINK_ATE //

#ifdef CONFIG_STA_SUPPORT


						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
						{
							// Read GPIO pin2 as Hardware controlled radio state

							RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);

							if (data & 0x04)
							{
								pAd->StaCfg.bHwRadio = TRUE;                                                                                                            
							} 
							else
							{
								pAd->StaCfg.bHwRadio = FALSE;                                                                                                           
							}                                                                                                                                               
	        	                                                                                                                                                        
							if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))                                                                    
							{                                                                                                                                               
								pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);                                                                    
								if(pAd->StaCfg.bRadio == TRUE)                                                                                                          
								{                                                                                                                                           
									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));  
	                                                                                                                            
									MlmeRadioOn(pAd);                                                                                                                       
									// Update extra information                                                                                                             
									pAd->ExtraInfo = EXTRA_INFO_CLEAR;                                                                                                      
								}                                                                                                                                           
								else                                                                                                                                        
								{                                                                                                                                           
									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
	                                                                                                                                    
									MlmeRadioOff(pAd);                                                                                                                      
									// Update extra information                                                                                                             
									pAd->ExtraInfo = HW_RADIO_OFF;                                                                                                          
								}                                                                                                                                           
							}
						}
#endif // CONFIG_STA_SUPPORT //
					}
					break;                                                                                                                                         
                                                                                                                                            
#ifdef CONFIG_STA_SUPPORT
				case CMDTHREAD_QKERIODIC_EXECUT:
					{
						StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
					}
					break;
#endif // CONFIG_STA_SUPPORT //

				case CMDTHREAD_RESET_BULK_OUT:                                                                                                                     
					{
						UINT32		MACValue;
						UCHAR		Index;
						int			ret=0;
						PHT_TX_CONTEXT	pHTTXContext;
//						RTMP_TX_RING *pTxRing;
						unsigned long IrqFlags;
						
						DBGPRINT(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", 
									pAd->bulkResetPipeid));
						// All transfers must be aborted or cancelled before attempting to reset the pipe.						
						//RTUSBCancelPendingBulkOutIRP(pAd);
						// Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
						Index = 0;
						do 
						{
							if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))								
								break;
							
							RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
							if ((MACValue & 0xf00000/*0x800000*/) == 0)
								break;
							Index++;
							RTMPusecDelay(10000);
						}while(Index < 100);
						MACValue = 0;
						RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						// 2nd, to prevent Read Register error, we check the validity.
						if ((MACValue & 0xc00000) == 0)
							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						// 3rd, to prevent Read Register error, we check the validity.
						if ((MACValue & 0xc00000) == 0)
							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						MACValue |= 0x80000;
						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);

						// Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
						RTMPusecDelay(1000);

						MACValue &= (~0x80000);
						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
						DBGPRINT(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
						
						// Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
						//RTMPusecDelay(5000);

						if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
						{
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
							if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
							{
								RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
							}
							RTUSBKickBulkOut(pAd);
							
							DBGPRINT(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
						}
						else
						{
							pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
							//NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
							RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
							if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
							{
								pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
								pHTTXContext->IRPPending = TRUE;
								pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
								
								// no matter what, clean the flag
								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
								
								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
#ifdef RALINK_ATE
								if(ATE_ON(pAd))				
							    {
									ret = ATEResetBulkOut(pAd);
								}
								else
#endif // RALINK_ATE //
								{
									RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, 
														pHTTXContext->BulkOutSize, 
														(usb_complete_t)RTUSBBulkOutDataPacketComplete);
								if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
								{
										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
									pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
									pHTTXContext->IRPPending = FALSE;
										pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);

										DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_OUT:Submit Tx URB failed %d\n", ret));
								} 
									else
									{
										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
										DBGPRINT(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n", 
												pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, 
												pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, 
												pAd->BulkOutPending[pAd->bulkResetPipeid]));
										DBGPRINT(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", 
															pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
										DBGPRINT(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->rtusb_urb_status));
									}
								}
							}
							else
							{
								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
								//RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
								
								DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", 
											pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
								if (pAd->bulkResetPipeid == 0)
								{
									UCHAR	pendingContext = 0;
									PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
									PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
									PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
									PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);

									if (pHTTXContext->IRPPending)
										pendingContext |= 1;
									else if (pMLMEContext->IRPPending)
										pendingContext |= 2;
									else if (pNULLContext->IRPPending)
										pendingContext |= 4;
									else if (pPsPollContext->IRPPending)
										pendingContext |= 8;
									else
										pendingContext = 0;
									
									DBGPRINT(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
								}

								// no matter what, clean the flag
								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);

								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
								
								RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
							}

							RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
							//RTUSBKickBulkOut(pAd);
						}

					}
					/*
						// Don't cancel BULKIN.	
						while ((atomic_read(&pAd->PendingRx) > 0) && 
								(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) 
						{
							if (atomic_read(&pAd->PendingRx) > 0)
							{
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
								RTUSBCancelPendingBulkInIRP(pAd);
							}
							RTMPusecDelay(100000);
						}
						
						if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
						{
							UCHAR	i;
							RTUSBRxPacket(pAd);
							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
							for (i = 0; i < (RX_RING_SIZE); i++)
							{
								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);

								pRxContext->pAd	= pAd;
								pRxContext->InUse		= FALSE;
								pRxContext->IRPPending	= FALSE;
								pRxContext->Readable	= FALSE;
								pRxContext->ReorderInUse = FALSE;
							
							}
							RTUSBBulkReceive(pAd);
							DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
						}*/
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
    	   			break;                                                                                                                                              
            	                                                                                                                                                    
				case CMDTHREAD_RESET_BULK_IN:                                                                                                                      
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));

					// All transfers must be aborted or cancelled before attempting to reset the pipe.
					{
						UINT32		MACValue;

#ifdef RALINK_ATE
						if (ATE_ON(pAd))
						{
							ATEResetBulkIn(pAd);
						}
						else
#endif // RALINK_ATE //
						{
						//while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) 
						if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
						{
							DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
							RTUSBCancelPendingBulkInIRP(pAd);
							RTMPusecDelay(100000);
							pAd->PendingRx = 0;
						}
						}						
						
						// Wait 10ms before reading register.
						RTMPusecDelay(10000);
						ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);

						if ((NT_SUCCESS(ntStatus) == TRUE) && 
							(!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | 
													fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
						{		
							UCHAR	i;

							if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | 
														fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
								break;
							pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
							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", 
									pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
							for (i = 0; i < RX_RING_SIZE; i++)
							{
 								DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
									, i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
							}
 							/*

							DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));

							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
							for (i = 0; i < (RX_RING_SIZE); i++)
							{
								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);

								pRxContext->pAd	= pAd;
								pRxContext->InUse		= FALSE;
								pRxContext->IRPPending	= FALSE;
								pRxContext->Readable	= FALSE;
								pRxContext->ReorderInUse = FALSE;
									
							}*/
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
							for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
							{
								//RTUSBBulkReceive(pAd);
								PRX_CONTEXT		pRxContext;
								PURB			pUrb;
								int				ret = 0;
								unsigned long	IrqFlags;

	
								RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
								pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
								if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
								{
									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
									break;
								}
								pRxContext->InUse = TRUE;
								pRxContext->IRPPending = TRUE;
								pAd->PendingRx++;
								pAd->BulkInReq++;
								RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);

								// Init Rx context descriptor
								RTUSBInitRxDesc(pAd, pRxContext);
								pUrb = pRxContext->pUrb;
								if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
								{	// fail
								
									RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
									pRxContext->InUse = FALSE;
									pRxContext->IRPPending = FALSE;
									pAd->PendingRx--;
									pAd->BulkInReq--;
									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
									DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->rtusb_urb_status));
								}
								else
								{	// success
									//DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", 
									//							pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex));
									DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->rtusb_urb_status));
									ASSERT((pRxContext->InUse == pRxContext->IRPPending));
								}
							}					

						}
						else
						{
							// Card must be removed
							if (NT_SUCCESS(ntStatus) != TRUE)
							{
								RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
							}
							else
							{
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
							}
						}                                                                                                                                                   
					}
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
					break;                                                                                                                                              
            	                                                                                                                                                    
				case CMDTHREAD_SET_ASIC_WCID:
					{
						RT_SET_ASIC_WCID	SetAsicWcid;
						USHORT		offset;
						UINT32		MACValue, MACRValue = 0;
						SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
						
						if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
							return;
						
						offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;

						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
						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]);
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
						RTUSBWriteMACRegister(pAd, offset, MACValue);
						// Read bitmask
						RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
						if ( SetAsicWcid.DeleteTid != 0xffffffff)
							MACRValue &= (~SetAsicWcid.DeleteTid);
						if (SetAsicWcid.SetTid != 0xffffffff)
							MACRValue |= (SetAsicWcid.SetTid);
						MACRValue &= 0xffff0000;
					
						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
						MACValue |= MACRValue;
						RTUSBWriteMACRegister(pAd, offset+4, MACValue);
						
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
					}
					break;

				/* Security Related for Asic command */	
				case CMDTHREAD_SET_WCID_SEC_INFO:
					{
						PRT_ASIC_WCID_SEC_INFO pInfo;

						pInfo = (PRT_ASIC_WCID_SEC_INFO)pData;
						RTMPSetWcidSecurityInfo(pAd, 
												pInfo->BssIdx, 
												pInfo->KeyIdx, 
												pInfo->CipherAlg, 
												pInfo->Wcid, 
												pInfo->KeyTabFlag);
					}
					break;
				
				case CMDTHREAD_SET_ASIC_WCID_IVEIV:
					{
						PRT_ASIC_WCID_IVEIV_ENTRY pInfo;

						pInfo = (PRT_ASIC_WCID_IVEIV_ENTRY)pData;
						AsicUpdateWCIDIVEIV(pAd, 
											pInfo->Wcid, 
											pInfo->Iv, 
											pInfo->Eiv);				
					}
					break;

				case CMDTHREAD_SET_ASIC_WCID_ATTR:
					{						
						PRT_ASIC_WCID_ATTR_ENTRY pInfo;

						pInfo = (PRT_ASIC_WCID_ATTR_ENTRY)pData;
						AsicUpdateWcidAttributeEntry(pAd, 
													 pInfo->BssIdx, 
													 pInfo->KeyIdx, 
													 pInfo->CipherAlg, 
													 pInfo->Wcid, 
													 pInfo->KeyTabFlag);
					}
					break;

				case CMDTHREAD_SET_ASIC_SHARED_KEY:
					{
						PRT_ASIC_SHARED_KEY pInfo;

						pInfo = (PRT_ASIC_SHARED_KEY)pData;
						AsicAddSharedKeyEntry(pAd, 
											  pInfo->BssIndex, 
											  pInfo->KeyIdx, 
											  &pInfo->CipherKey);
					}
					break;

				case CMDTHREAD_SET_ASIC_PAIRWISE_KEY:
					{
						PRT_ASIC_PAIRWISE_KEY pInfo;

						pInfo = (PRT_ASIC_PAIRWISE_KEY)pData;
						AsicAddPairwiseKeyEntry(pAd, 
												pInfo->WCID, 
												&pInfo->CipherKey);
					}
					break;

				case CMDTHREAD_SET_PORT_SECURED:
					{
#ifdef CONFIG_STA_SUPPORT
						STA_PORT_SECURED(pAd);
#endif // CONFIG_STA_SUPPORT //
					}
					break;
					
				case CMDTHREAD_REMOVE_PAIRWISE_KEY:
					{
						UCHAR Wcid = *((PUCHAR)(pData));	
						AsicRemovePairwiseKeyEntry(pAd, Wcid);						
					}
					break;
					
				case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
					{
						PRT_SET_ASIC_WCID pInfo;

						pInfo = (PRT_SET_ASIC_WCID)pData;						
						AsicUpdateRxWCIDTable(pAd, pInfo->WCID, pInfo->Addr);
					}
					break;

// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
				case CMDTHREAD_UPDATE_PROTECT:
					{
						AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
					}
					break;
// end johnli

				case CMDTHREAD_802_11_COUNTER_MEASURE:
					break;
					
#ifdef CONFIG_STA_SUPPORT
				case CMDTHREAD_SET_PSM_BIT:
					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
					{
						USHORT *pPsm = (USHORT *)pData;
						MlmeSetPsmBit(pAd, *pPsm);
					}
					break;
				case CMDTHREAD_FORCE_WAKE_UP:
					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
						AsicForceWakeup(pAd, TRUE);
					break;
				case CMDTHREAD_FORCE_SLEEP_AUTO_WAKEUP:
				{
					USHORT  TbttNumToNextWakeUp;
					USHORT  NextDtim = pAd->StaCfg.DtimPeriod;
					ULONG   Now;

					NdisGetSystemUpTime(&Now);
					NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;

					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
						TbttNumToNextWakeUp = NextDtim;

					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
					// if WMM-APSD is failed, try to disable following line
					AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
				}
					break;
#endif // CONFIG_STA_SUPPORT //




				default:
					DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
					break;                                                                                                                                              
			}                                                                                                                                                       
		}                                                                                                                                                          
                                                                                                                                                                
		if (cmdqelmt->CmdFromNdis == TRUE)
		{
			if (cmdqelmt->buffer != NULL)
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		}
		else
		{
			if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		}
	}	/* end of while */
}
コード例 #2
0
/*
========================================================================
Routine Description:
    USB command kernel thread.

Arguments:
	*Context			the pAd, driver control block pointer

Return Value:
    0					close the thread

Note:
========================================================================
*/
INT RTUSBCmdThread(
    IN ULONG Context)
{
    RTMP_ADAPTER *pAd;
    RTMP_OS_TASK *pTask;
    int status;
    status = 0;

    pTask = (RTMP_OS_TASK *)Context;
    pAd = (PRTMP_ADAPTER)pTask->priv;

    RtmpOSTaskCustomize(pTask);

    NdisAcquireSpinLock(&pAd->CmdQLock);
    pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
    NdisReleaseSpinLock(&pAd->CmdQLock);

    while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING)
    {
#ifdef KTHREAD_SUPPORT
        RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
        /* lock the device pointers */
        RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);

        if (status != 0)
        {
            RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
            break;
        }
#endif

        if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
            break;

        if (!pAd->PM_FlgSuspend)
            CMDHandler(pAd);
    }

    if (pAd && !pAd->PM_FlgSuspend)
    {   // Clear the CmdQElements.
        CmdQElmt	*pCmdQElmt = NULL;

        NdisAcquireSpinLock(&pAd->CmdQLock);
        pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
        while(pAd->CmdQ.size)
        {
            RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
            if (pCmdQElmt)
            {
                if (pCmdQElmt->CmdFromNdis == TRUE)
                {
                    if (pCmdQElmt->buffer != NULL)
                        os_free_mem(pAd, pCmdQElmt->buffer);
                    os_free_mem(pAd, (PUCHAR)pCmdQElmt);
                }
                else
                {
                    if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
                        os_free_mem(pAd, pCmdQElmt->buffer);
                    os_free_mem(pAd, (PUCHAR)pCmdQElmt);
                }
            }
        }

        NdisReleaseSpinLock(&pAd->CmdQLock);
    }
    /* notify the exit routine that we're actually exiting now
     *
     * complete()/wait_for_completion() is similar to up()/down(),
     * except that complete() is safe in the case where the structure
     * is getting deleted in a parallel mode of execution (i.e. just
     * after the down() -- that's necessary for the thread-shutdown
     * case.
     *
     * complete_and_exit() goes even further than this -- it is safe in
     * the case that the thread of the caller is going away (not just
     * the structure) -- this is necessary for the module-remove case.
     * This is important in preemption kernels, which transfer the flow
     * of execution immediately upon a complete().
     */
    DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));

#ifndef KTHREAD_SUPPORT
    pTask->taskPID = THREAD_PID_INIT_VALUE;
    complete_and_exit (&pTask->taskComplete, 0);
#endif
    return 0;

}
コード例 #3
0
ファイル: rt_usb.c プロジェクト: 1950packard/rt3573sta
/*
========================================================================
Routine Description:
    USB command kernel thread.

Arguments:
	*Context			the pAd, driver control block pointer

Return Value:
    0					close the thread

Note:
========================================================================
*/
INT RTUSBCmdThread(
	IN ULONG Context)
{
	RTMP_ADAPTER *pAd;
	RTMP_OS_TASK *pTask;
	int status;
	status = 0;

	pTask = (RTMP_OS_TASK *)Context;
	pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask);
	
	if (pAd == NULL)
		return 0;
	
	RtmpOSTaskCustomize(pTask);

	NdisAcquireSpinLock(&pAd->CmdQLock);
	pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
	NdisReleaseSpinLock(&pAd->CmdQLock);
	
	while (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING)
	{
		if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE)
		{
			DBGPRINT_ERR(("RtmpOSTaskWait returned false in RTUSBCmdThread, setting halt in progress flag!\n"));
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
			break;
		}

		if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
			break;

		if (!pAd->PM_FlgSuspend)
			CMDHandler(pAd);
	}

	if (!pAd->PM_FlgSuspend)
	{	/* Clear the CmdQElements. */
		CmdQElmt	*pCmdQElmt = NULL;

		NdisAcquireSpinLock(&pAd->CmdQLock);
		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
		while(pAd->CmdQ.size)
		{
			RTThreadDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
			if (pCmdQElmt)
			{
				if (pCmdQElmt->CmdFromNdis == TRUE)
				{
					if (pCmdQElmt->buffer != NULL)
						os_free_mem(pAd, pCmdQElmt->buffer);
					os_free_mem(pAd, (PUCHAR)pCmdQElmt);
				}
				else
				{
					if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
						os_free_mem(pAd, pCmdQElmt->buffer);
					os_free_mem(pAd, (PUCHAR)pCmdQElmt);
				}
			}
		}

		NdisReleaseSpinLock(&pAd->CmdQLock);
	}
	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));

	RtmpOSTaskNotifyToExit(pTask);
	return 0;

}