Exemplo n.º 1
0
/*
 * --------------------------------------------------------------------------
 *  Implements filter driver's FilterAttach function.
 *
 *  This function allocates the switch context, and initializes its necessary
 *  members.
 * --------------------------------------------------------------------------
 */
NDIS_STATUS
OvsExtAttach(NDIS_HANDLE ndisFilterHandle,
             NDIS_HANDLE filterDriverContext,
             PNDIS_FILTER_ATTACH_PARAMETERS attachParameters)
{
    NDIS_STATUS status = NDIS_STATUS_FAILURE;
    NDIS_FILTER_ATTRIBUTES ovsExtAttributes;
    POVS_SWITCH_CONTEXT switchContext = NULL;

    UNREFERENCED_PARAMETER(filterDriverContext);

    OVS_LOG_TRACE("Enter: ndisFilterHandle %p", ndisFilterHandle);

    ASSERT(filterDriverContext == (NDIS_HANDLE)gOvsExtDriverObject);
    if (attachParameters->MiniportMediaType != NdisMedium802_3) {
        status = NDIS_STATUS_INVALID_PARAMETER;
        goto cleanup;
    }

    if (gOvsExtDriverHandle == NULL) {
        OVS_LOG_TRACE("Exit: OVSEXT driver is not loaded.");
        ASSERT(FALSE);
        goto cleanup;
    }

    NdisAcquireSpinLock(gOvsCtrlLock);
    if (gOvsSwitchContext) {
        NdisReleaseSpinLock(gOvsCtrlLock);
        OVS_LOG_TRACE("Exit: Failed to create OVS Switch, only one datapath is"
                      "supported, %p.", gOvsSwitchContext);
        goto cleanup;
    }
    if (gOvsInAttach) {
        NdisReleaseSpinLock(gOvsCtrlLock);
        /* Just fail the request. */
        OVS_LOG_TRACE("Exit: Failed to create OVS Switch, since another attach"
                      "instance is in attach process.");
        goto cleanup;
    }
    gOvsInAttach = TRUE;
    NdisReleaseSpinLock(gOvsCtrlLock);

    status = OvsInitIpHelper(ndisFilterHandle);
    if (status != STATUS_SUCCESS) {
        OVS_LOG_ERROR("Exit: Failed to initialize IP helper.");
        goto cleanup;
    }

    status = OvsCreateSwitch(ndisFilterHandle, &switchContext);
    if (status != NDIS_STATUS_SUCCESS) {
        OvsCleanupIpHelper();
        goto cleanup;
    }
    ASSERT(switchContext);

    /*
     * Register the switch context with NDIS so NDIS can pass it back to the
     * Filterxxx callback functions as the 'FilterModuleContext' parameter.
     */
    RtlZeroMemory(&ovsExtAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
    ovsExtAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
    ovsExtAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
    ovsExtAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
    ovsExtAttributes.Flags = 0;

    NDIS_DECLARE_FILTER_MODULE_CONTEXT(OVS_SWITCH_CONTEXT);
    status = NdisFSetAttributes(ndisFilterHandle, switchContext, &ovsExtAttributes);
    if (status != NDIS_STATUS_SUCCESS) {
        OVS_LOG_ERROR("Failed to set attributes.");
        OvsCleanupIpHelper();
        goto cleanup;
    }

    /* Setup the state machine. */
    switchContext->controlFlowState = OvsSwitchAttached;
    switchContext->dataFlowState = OvsSwitchPaused;

    gOvsSwitchContext = switchContext;
    KeMemoryBarrier();

cleanup:
    gOvsInAttach = FALSE;
    if (status != NDIS_STATUS_SUCCESS) {
        if (switchContext != NULL) {
            OvsDeleteSwitch(switchContext);
        }
    }
    OVS_LOG_TRACE("Exit: status %x", status);

    return status;
}
Exemplo n.º 2
0
int divert_filter_send(PADAPT pAdapt, PNDIS_PACKET Packet, int in)
{
#define HDR_SIZE 54
	int len, cnt;
	PNDIS_BUFFER buf;
	char crap[HDR_SIZE];
	int rc = 0, rd;
	struct ether_header  *pEthHdr;      // See ../B2Winet/ethernet.h
	struct ip            *pIPHeader;
	struct tcphdr	     *tcp;
	struct divert_packet *dp;
	int off = 0; // 14;
        NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;

	NdisAcquireSpinLock(&pAdapt->Lock);

	NdisQueryPacket(Packet, NULL, &cnt, &buf, &len);

	if (len < HDR_SIZE)
		goto Out;

	FltReadOnPacket(Packet, crap, HDR_SIZE, 0, &rd);
	if (rd < HDR_SIZE)
		goto Out;

	pEthHdr = (struct ether_header*) crap;
	pEthHeader = pEthHdr;

	if (ntohs( pEthHdr->ether_type ) != ETHERTYPE_IP)
		goto Out;

	if (in && get_pa(pEthHeader->SrcAddr))
		goto Out;

	pIPHeader = (struct ip * ) (pEthHdr + 1);

	if (pIPHeader->ip_p != IPPROTO_TCP)
		goto Out;

	tcp	  = (struct tcphr*) (pIPHeader + 1);

#if 0
	if (ntohs(tcp->th_dport) == 666)
		rc = 1;
#endif

	lock();

	if (!_open)
		goto F**k;

	dp = get_packet();
	if (!dp) {
		DbgPrint("divert_packet() - outta space dude\n");
		goto F**k;
	}

	dp->dp_len = len - off;
	FltReadOnPacket(Packet, dp->dp_packet, dp->dp_len, off, &rd);
//	rd = dp->dp_len;
	if (rd != dp->dp_len)
		goto F**k;

	dp->dp_flags = 1;

	kick_pending();

	rc = 1;

F**k:
	unlock();
Out:
	NdisReleaseSpinLock(&pAdapt->Lock);

	return rc;
#undef HDR_SIZE
}
Exemplo n.º 3
0
/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	Note:

	========================================================================
*/
VOID	RTUSBCancelPendingBulkOutIRP(
	IN	PRTMP_ADAPTER	pAd)
{
	PHT_TX_CONTEXT		pHTTXContext;
	PTX_CONTEXT			pMLMEContext;
	PTX_CONTEXT			pBeaconContext;
	PTX_CONTEXT			pNullContext;
	PTX_CONTEXT			pPsPollContext;
	PTX_CONTEXT			pRTSContext;
	UINT				i, Idx;
//	unsigned int 		IrqFlags;
//	NDIS_SPIN_LOCK		*pLock;
//	BOOLEAN				*pPending;


//	pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
//	pPending = &pAd->BulkOutPending[MGMTPIPEIDX];

	for (Idx = 0; Idx < 4; Idx++)
	{
		pHTTXContext = &(pAd->TxContext[Idx]);

		if (pHTTXContext->IRPPending == TRUE)
		{

			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
			//

			RTUSB_UNLINK_URB(pHTTXContext->pUrb);

			// Sleep 200 microseconds to give cancellation time to work
			RTMPusecDelay(200);
		}

		pAd->BulkOutPending[Idx] = FALSE;
	}

	//RTMP_IRQ_LOCK(pLock, IrqFlags);
	for (i = 0; i < MGMT_RING_SIZE; i++)
	{
		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
		if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
		{

			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
			//

			RTUSB_UNLINK_URB(pMLMEContext->pUrb);
			pMLMEContext->IRPPending = FALSE;

			// Sleep 200 microsecs to give cancellation time to work
			RTMPusecDelay(200);
		}
	}
	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
	//RTMP_IRQ_UNLOCK(pLock, IrqFlags);


	for (i = 0; i < BEACON_RING_SIZE; i++)
	{
		pBeaconContext = &(pAd->BeaconContext[i]);

		if(pBeaconContext->IRPPending == TRUE)
		{

			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
			//

			RTUSB_UNLINK_URB(pBeaconContext->pUrb);

			// Sleep 200 microsecs to give cancellation time to work
			RTMPusecDelay(200);
		}
	}

	pNullContext = &(pAd->NullContext);
	if (pNullContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pNullContext->pUrb);

	pRTSContext = &(pAd->RTSContext);
	if (pRTSContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pRTSContext->pUrb);

	pPsPollContext = &(pAd->PsPollContext);
	if (pPsPollContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pPsPollContext->pUrb);

	for (Idx = 0; Idx < 4; Idx++)
	{
		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
		pAd->BulkOutPending[Idx] = FALSE;
		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
	}
}
Exemplo n.º 4
0
REPEATER_CLIENT_ENTRY *RTMPLookupRepeaterCliEntry(
	IN PVOID pData,
	IN BOOLEAN bRealMAC,
	IN PUCHAR pAddr,
	IN BOOLEAN bIsPad,
	OUT PUCHAR pIsLinkValid)
{
	ULONG HashIdx;
	UCHAR tempMAC[6];
	REPEATER_CLIENT_ENTRY *pEntry = NULL;
	REPEATER_CLIENT_ENTRY_MAP *pMapEntry = NULL;

	if (bIsPad == TRUE) {
		NdisAcquireSpinLock(&((PRTMP_ADAPTER)pData)->ApCfg.ReptCliEntryLock);	
	} else {
		NdisAcquireSpinLock(((REPEATER_ADAPTER_DATA_TABLE *)pData)->EntryLock);
	}
	
	COPY_MAC_ADDR(tempMAC, pAddr);
	HashIdx = MAC_ADDR_HASH_INDEX(tempMAC);
    *pIsLinkValid = TRUE;

	if (bRealMAC == TRUE)
	{
		if (bIsPad == TRUE) {
			pMapEntry = ((PRTMP_ADAPTER)pData)->ApCfg.ReptMapHash[HashIdx];
		} else
			pMapEntry = *((((REPEATER_ADAPTER_DATA_TABLE *)pData)->MapHash) + HashIdx) ;

		
		while (pMapEntry)
		{
			pEntry = pMapEntry->pReptCliEntry;

			if (MAC_ADDR_EQUAL(pEntry->OriginalAddress, tempMAC))
			{
				if (pEntry->CliValid == FALSE) {
					*pIsLinkValid = FALSE;
					pEntry = NULL;
				}
				
				break;			
			}
			else
			{
				pEntry = NULL;
				pMapEntry = pMapEntry->pNext;
			}
		}
	}
	else
	{
		if (bIsPad == TRUE) {
			pEntry = ((PRTMP_ADAPTER)pData)->ApCfg.ReptCliHash[HashIdx];
		} else {
			pEntry = *((((REPEATER_ADAPTER_DATA_TABLE *)pData)->CliHash) + HashIdx) ;
		}

		while (pEntry)
		{
			if (MAC_ADDR_EQUAL(pEntry->CurrentAddress, tempMAC))
			{
				if (pEntry->CliValid == FALSE) {
					*pIsLinkValid = FALSE;
					pEntry = NULL;
				}
				break;
			}
			else
				pEntry = pEntry->pNext;
		}
	}

	if (bIsPad == TRUE) {
		NdisReleaseSpinLock(&((PRTMP_ADAPTER)pData)->ApCfg.ReptCliEntryLock);
	} else {
		NdisReleaseSpinLock(((REPEATER_ADAPTER_DATA_TABLE *)pData)->EntryLock);
	}

	return pEntry;
}
Exemplo n.º 5
0
MAC_TABLE_ENTRY *RTMPInsertRepeaterMacEntry(
	IN  RTMP_ADAPTER *pAd,
	IN  UCHAR *pAddr,
	IN  struct wifi_dev *wdev,
	IN  UCHAR apIdx,
	IN  UCHAR cliIdx,
	IN BOOLEAN CleanAll)
{
	UCHAR HashIdx;
	int i;
	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
	BOOLEAN Cancelled;

	/* if FULL, return*/
	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
		return NULL;

	/* allocate one MAC entry*/
	NdisAcquireSpinLock(&pAd->MacTabLock);

	i = (MAX_NUMBER_OF_MAC + ((MAX_EXT_MAC_ADDR_SIZE + 1) * (apIdx - MIN_NET_DEVICE_FOR_APCLI)));

	if (cliIdx != 0xFF)
		i  = i + cliIdx + 1;

	/* pick up the first available vacancy*/
	pEntry = &pAd->MacTab.Content[i];

	if (pEntry == NULL)
	{
		printk("###### %s pEntry == NULL, i = %d\n", __func__, i);
	}

	if (pEntry && IS_ENTRY_NONE(pEntry))
	{
		/* ENTRY PREEMPTION: initialize the entry */
		if (pEntry->RetryTimer.Valid)
			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
		if (pEntry->EnqueueStartForPSKTimer.Valid)
			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);

		NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));

		if (CleanAll == TRUE)
		{
			pEntry->MaxSupportedRate = RATE_11;
			pEntry->CurrTxRate = RATE_11;
			NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
			pEntry->PairwiseKey.KeyLen = 0;
			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
		}

		SET_ENTRY_APCLI(pEntry);
		pEntry->wdev = wdev;
		pEntry->wcid = i;
		pEntry->isCached = FALSE;
		pEntry->bIAmBadAtheros = FALSE;

		RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE);
		RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE);

#ifdef TXBF_SUPPORT
		if (pAd->chipCap.FlgHwTxBfCap)
			RTMPInitTimer(pAd, &pEntry->eTxBfProbeTimer, GET_TIMER_FUNCTION(eTxBfProbeTimerExec), pEntry, FALSE);
#endif /* TXBF_SUPPORT */

		pEntry->pAd = pAd;
		pEntry->CMTimerRunning = FALSE;
		pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
		pEntry->RSNIE_Len = 0;
		NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
		pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
		pEntry->apidx = (apIdx - MIN_NET_DEVICE_FOR_APCLI);
		pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx];

		pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->apidx].wdev.AuthMode;
		pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->apidx].wdev.WepStatus;
		pEntry->wdev_idx = pEntry->apidx;

		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
		{
			pEntry->WpaState = AS_NOTUSE;
			pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
		}
		else
		{
			pEntry->WpaState = AS_PTKSTART;
			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
		}

		pEntry->GTKState = REKEY_NEGOTIATING;
		pEntry->PairwiseKey.KeyLen = 0;
		pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
		pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;

		pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
		COPY_MAC_ADDR(pEntry->Addr, pAddr);
		//COPY_MAC_ADDR(pEntry->HdrAddr1, pAddr);
		//COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.ApCliTab[pEntry->apidx].CurrentAddress);
		//COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr);
		COPY_MAC_ADDR(pEntry->bssid, pAddr);

		pEntry->Sst = SST_NOT_AUTH;
		pEntry->AuthState = AS_NOT_AUTH;
		pEntry->Aid = (USHORT)i;  /*0;*/
		pEntry->CapabilityInfo = 0;
		pEntry->PsMode = PWR_ACTIVE;
		pEntry->PsQIdleCount = 0;
		pEntry->NoDataIdleCount = 0;
		pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
		pEntry->ContinueTxFailCnt = 0;
		pEntry->TimeStamp_toTxRing = 0;
		InitializeQueueHeader(&pEntry->PsQueue);

#ifdef PS_ENTRY_MAITENANCE
		pEntry->continuous_ps_count = 0;
#endif /* PS_ENTRY_MAITENANCE */

		pAd->MacTab.Size ++;

		/* Set the security mode of this entry as OPEN-NONE in ASIC */
		RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i);

		/* Add this entry into ASIC RX WCID search table */
		RTMP_STA_ENTRY_ADD(pAd, pEntry);

#ifdef WSC_AP_SUPPORT
		pEntry->bWscCapable = FALSE;
		pEntry->Receive_EapolStart_EapRspId = 0;
#endif /* WSC_AP_SUPPORT */

#ifdef TXBF_SUPPORT
		if (pAd->chipCap.FlgHwTxBfCap)
			NdisAllocateSpinLock(pAd, &pEntry->TxSndgLock);
#endif /* TXBF_SUPPORT */

#ifdef PEER_DELBA_TX_ADAPT
		Peer_DelBA_Tx_Adapt_Init(pAd, pEntry);
#endif /* PEER_DELBA_TX_ADAPT */
#ifdef DROP_MASK_SUPPORT
		drop_mask_init_per_client(pAd, pEntry);
#endif /* DROP_MASK_SUPPORT */

#ifdef FIFO_EXT_SUPPORT
		if (pAd->chipCap.FlgHwFifoExtCap)
		{
			UCHAR tblIdx;

			if ((cliIdx != 0xFF) && IsFifoExtTblAvailable(pAd, &tblIdx))
				FifoExtTblUpdateEntry(pAd, tblIdx, i);
		}
#endif
		DBGPRINT(RT_DEBUG_TRACE, ("%s - allocate entry #%d, Aid = %d, Wcid = %d Addr(%02x:%02x:%02x:%02x:%02x:%02x) Total= %d\n",__FUNCTION__, i, 
		pEntry->Aid, pEntry->wcid, PRINT_MAC(pEntry->Addr), pAd->MacTab.Size));
	}
	else
	{
		DBGPRINT(RT_DEBUG_ERROR, ("%s - exist entry #%d, Aid = %d, Total= %d\n", __FUNCTION__, i, pEntry->Aid, pAd->MacTab.Size));
		NdisReleaseSpinLock(&pAd->MacTabLock);
		return pEntry;
	}

	/* add this MAC entry into HASH table */
	if (pEntry)
	{
		pEntry->pNext = NULL;

		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
		if (pAd->MacTab.Hash[HashIdx] == NULL)
		{
			pAd->MacTab.Hash[HashIdx] = pEntry;
		}
		else
		{
			pCurrEntry = pAd->MacTab.Hash[HashIdx];
			while (pCurrEntry->pNext != NULL)
				pCurrEntry = pCurrEntry->pNext;
			pCurrEntry->pNext = pEntry;
		}
	}

	NdisReleaseSpinLock(&pAd->MacTabLock);
	return pEntry;
}
Exemplo n.º 6
0
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 */
}
/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingBulkOutIRP(
	IN	PRTMP_ADAPTER	pAd)
{
	PHT_TX_CONTEXT		pHTTXContext;
	PTX_CONTEXT			pMLMEContext;
	PTX_CONTEXT			pNullContext;
	PTX_CONTEXT			pPsPollContext;
	UINT				i, Idx;
/*	unsigned int 		IrqFlags;*/
/*	NDIS_SPIN_LOCK		*pLock;*/
/*	BOOLEAN				*pPending;*/
	

/*	pLock = &pAd->BulkOutLock[MGMTPIPEIDX];*/
/*	pPending = &pAd->BulkOutPending[MGMTPIPEIDX];*/

	for (Idx = 0; Idx < 4; Idx++)
	{
		pHTTXContext = &(pAd->TxContext[Idx]);

		if (pHTTXContext->IRPPending == TRUE)
		{

			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/
			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/
			/*	when the last IRP on the list has been	cancelled; that's how we exit this loop*/
			

			RTUSB_UNLINK_URB(pHTTXContext->pUrb);

			/* Sleep 200 microseconds to give cancellation time to work*/
			RTMPusecDelay(200);
		}

#ifdef RALINK_ATE
		pHTTXContext->bCopySavePad = 0;
		pHTTXContext->CurWritePosition = 0;
		pHTTXContext->CurWriteRealPos = 0;
		pHTTXContext->bCurWriting = FALSE;
		pHTTXContext->NextBulkOutPosition = 0;
		pHTTXContext->ENextBulkOutPosition = 0;
#endif /* RALINK_ATE */
		pAd->BulkOutPending[Idx] = FALSE;
	}

	/*RTMP_IRQ_LOCK(pLock, IrqFlags);*/
	for (i = 0; i < MGMT_RING_SIZE; i++)
	{
		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
		if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
		{

			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/
			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/
			/*	when the last IRP on the list has been	cancelled; that's how we exit this loop*/
			

			RTUSB_UNLINK_URB(pMLMEContext->pUrb);
			pMLMEContext->IRPPending = FALSE;
			
			/* Sleep 200 microsecs to give cancellation time to work*/
			RTMPusecDelay(200);
		}
	}
	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
	/*RTMP_IRQ_UNLOCK(pLock, IrqFlags);*/

	pNullContext = &(pAd->NullContext);
	if (pNullContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pNullContext->pUrb);

	pPsPollContext = &(pAd->PsPollContext);
	if (pPsPollContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pPsPollContext->pUrb);

	for (Idx = 0; Idx < 4; Idx++)
	{
		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
		pAd->BulkOutPending[Idx] = FALSE;
		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
	}
}
Exemplo n.º 8
0
NTSTATUS
ssh_interceptor_iodevice_dispatch_ioctl(PDEVICE_OBJECT device,
                                        PIRP irp)
{
#ifdef HAS_IOCTL_HANDLERS
  PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(irp);
  ULONG ioctl_code = io_stack->Parameters.DeviceIoControl.IoControlCode;
  SshInterceptorIoDevice io_dev = SSH_NTDEV_TO_SSHDEV(device);
  SshIoDeviceIoctlHandler handler = NULL;
  PLIST_ENTRY entry;

  NdisAcquireSpinLock(&io_dev->ioctl_handler_list_lock);
  entry = io_dev->ioctl_handler_list.Flink;
  while (entry != &io_dev->ioctl_handler_list)
    {
      SshIoDeviceIoctlHandler h;

      h = CONTAINING_RECORD(entry, SshIoDeviceIoctlHandlerStruct, link);

      if (h->ioctl_code == ioctl_code)
        {
          handler = h;
          InterlockedIncrement(&handler->ref_count);
          break;
        }

      entry = entry->Flink;
    }
  NdisReleaseSpinLock(&io_dev->ioctl_handler_list_lock);

  if (handler != NULL)
    {
      SshIoDeviceIoctlRequest ioctl;




      ioctl = ssh_calloc(1, sizeof(*ioctl));
      if (ioctl == NULL)
        {
          irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
          irp->IoStatus.Information = 0;
          IoCompleteRequest(irp, IO_NO_INCREMENT);

          return STATUS_UNSUCCESSFUL;
        }

      /* Initialize te IOCTL request */
      ioctl->public_data.device = io_dev;
      ioctl->public_data.ioctl_code = ioctl_code;
      ioctl->public_data.context = handler;                  
      ioctl->public_data.cancel_id = ioctl; 
      ioctl->public_data.input_buf_len = 
        io_stack->Parameters.DeviceIoControl.InputBufferLength;
      ioctl->public_data.output_buf_len = 
        io_stack->Parameters.DeviceIoControl.OutputBufferLength;

      switch (ioctl_code & 0x00000003)
        {
        case METHOD_BUFFERED:
          ioctl->public_data.input_buf = irp->AssociatedIrp.SystemBuffer;
          ioctl->public_data.output_buf = irp->AssociatedIrp.SystemBuffer;
          break;

        case METHOD_NEITHER:
          ioctl->public_data.input_buf = 
            io_stack->Parameters.DeviceIoControl.Type3InputBuffer;
          ioctl->public_data.output_buf = irp->UserBuffer;
          break;




        case METHOD_IN_DIRECT:  
        case METHOD_OUT_DIRECT:
        default:
          SSH_NOTREACHED;
          break;
        }
      ioctl->public_data.bytes_read = 0;
      ioctl->public_data.bytes_written = 0;
      ioctl->private_data.irp = irp;
      NdisAcquireSpinLock(&io_dev->ioctl_req_list_lock);
      InsertTailList(&io_dev->active_ioctl_req_list,
		     &ioctl->private_data.link);
      NdisReleaseSpinLock(&io_dev->ioctl_req_list_lock);

      irp->IoStatus.Status = STATUS_PENDING;
      IoMarkIrpPending(irp);

#pragma warning(disable: 4311 4312)
      IoSetCancelRoutine(irp, ssh_interceptor_iodevice_cancel_queued_ioctl);
#pragma warning(default: 4311 4312)

      (*(handler->ioctl_handler))(handler->context, &ioctl->public_data);

      return STATUS_PENDING;
    }
#endif /* HAS_IOCTL_HANDLERS */

  irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  irp->IoStatus.Information = 0;
  IoCompleteRequest(irp, IO_NO_INCREMENT);

  return STATUS_NOT_SUPPORTED;
}
Exemplo n.º 9
0
static void 
ssh_interceptor_iodevice_do_reads(SshInterceptorIoDevice io_dev)
{
  SshDeviceBuffer buffer;
  PIO_STACK_LOCATION irp_stack = NULL;
  char *dest = NULL;
  char *base_addr = NULL;
  PIRP irp = NULL;

  NdisAcquireSpinLock(&io_dev->output_queue_lock);
  buffer = io_dev->current_read_buf;
  NdisReleaseSpinLock(&io_dev->output_queue_lock);

  /* Complete as many queued output buffers and pending reads as possible */
  while (TRUE)
    {
      PLIST_ENTRY entry;
      unsigned bytes_copied;

      /* Try to find some data to write */
      if (buffer == NULL)
        {
          NdisAcquireSpinLock(&io_dev->output_queue_lock);
          if (!IsListEmpty(&io_dev->output_queue))
            {
              entry = RemoveHeadList(&io_dev->output_queue);
              buffer = CONTAINING_RECORD(entry, SshDeviceBufferStruct, link);
              /* If this is an unreliable message, it must also be removed
                 from the unreliable_output_queue! */
              if (buffer->reliable == 0)
                RemoveEntryList(&buffer->unreliable_list_link);
            }
          io_dev->current_read_buf = buffer;
          NdisReleaseSpinLock(&io_dev->output_queue_lock);

          /* Exit the loop if no data was available in output queue */
          if (buffer == NULL)
            goto complete;  
        }

      /* Try to find queued read IRP */
      if (irp == NULL)
        {
          entry = NdisInterlockedRemoveHeadList(&io_dev->read_queue,
                                                &io_dev->read_queue_lock);
          if (entry)
            {
              irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
              irp_stack = IoGetCurrentIrpStackLocation(irp);

              /* There is no need to check for canceled status, because
                 cancelation is protected by the same lock as the queue
                 itself. We may actually pop off an IRP for which cancel
                 has already been issued, but we can complete it as usual. */
#pragma warning(disable: 4311 4312)
              IoSetCancelRoutine(irp, NULL);
#pragma warning(default: 4311 4312)
              irp->IoStatus.Information = 0;
              irp->IoStatus.Status = STATUS_SUCCESS;

              base_addr = ssh_iodevice_map_buffer(irp->MdlAddress);
              if (base_addr == NULL)
                {
                  /* Mapping of user-mode buffer could fail if the system is
                     very low on resources. */
                  IoCompleteRequest(irp, IO_NETWORK_INCREMENT);
                  irp = NULL;
                  continue;
                }

              dest = base_addr;
            }
          else
            {
              /* No read IRPs available, exit the loop */
              goto complete;
            }
        }

      /* We copy either the whole buffer or part of it if there isn't enough
         space left in the currently processed read IRP. */
      bytes_copied = buffer->len;
      if (irp->IoStatus.Information + bytes_copied >
          irp_stack->Parameters.Read.Length)
        {
          bytes_copied = irp_stack->Parameters.Read.Length -
                         (unsigned int)irp->IoStatus.Information;
        }

      NdisMoveMemory(dest, buffer->addr + buffer->offset, bytes_copied);

      buffer->offset += bytes_copied;
      buffer->len -= bytes_copied;
      if (buffer->len == 0)
        {
          NdisAcquireSpinLock(&io_dev->output_queue_lock);
          io_dev->current_read_buf = NULL;
          NdisReleaseSpinLock(&io_dev->output_queue_lock);

          ssh_iodevice_buffer_free(io_dev, buffer); 

          buffer = NULL;
        }

      irp->IoStatus.Information += bytes_copied;
      dest += bytes_copied;

      /* If the IRP is now "full", complete the request */
      if (irp->IoStatus.Information == irp_stack->Parameters.Read.Length)
        {
          ssh_iodevice_unmap_buffer(base_addr, irp->MdlAddress);
          IoCompleteRequest(irp, IO_NETWORK_INCREMENT);
          irp = NULL;
          base_addr = NULL;
        }
    }

complete:

  /* We should also complete the partially filled IRP, if any */
  if (irp)
    {
      ssh_iodevice_unmap_buffer(base_addr, irp->MdlAddress);
      IoCompleteRequest(irp, IO_NETWORK_INCREMENT);
    }
}
Exemplo n.º 10
0
VOID
ElnkStagedAllocation(
    IN PELNK_ADAPTER Adapter
    )

/*++

Routine Description:

    This routine attempts to take a packet through a stage of allocation.

Arguments:

    Adapter - The adapter that the packets are coming through.

Return Value:

    None.

--*/

{
    UINT CbIndex;

    PNDIS_PACKET FirstPacket = Adapter->FirstStagePacket;

    if ELNKDEBUG DPrint1("StagedAllocation\n");
    //
    // For each stage, we check to see that it is open,
    // that somebody else isn't already processing,
    // and that there is some work from the previous
    // stage to do.
    //

    ASSERT (Adapter->StageOpen &&
            !Adapter->AlreadyProcessingStage &&
            Adapter->FirstStagePacket);

    //
    // If we successfully acquire a command block, this
    // is the index to it.
    //

    Adapter->AlreadyProcessingStage = TRUE;

    //
    // We look to see if there is an available Command Block.
    // If there isn't then stage 2 will close.
    //

    IF_LOG('p');

    if (ElnkAcquireCommandBlock(
        Adapter,
        &CbIndex
        )) {

        IF_LOG('a');

        //
        // Remove from queue
        //

        Adapter->FirstStagePacket = PELNK_RESERVED_FROM_PACKET(FirstPacket)->Next;

        if (!Adapter->FirstStagePacket) {

            Adapter->LastStagePacket = NULL;

        }

        NdisReleaseSpinLock(&Adapter->Lock);

        //
        // We have a command block.  Assign all packet
        // buffers to the command block.
        //

        ElnkAssignPacketToCommandBlock(
            Adapter,
            FirstPacket,
            CbIndex
            );

        //
        // We need exclusive access to the Command Queue so
        // that we can move this packet on to the next stage.
        //

        NdisAcquireSpinLock(&Adapter->Lock);

        ElnkPutPacketOnFinishTrans(
                Adapter,
                FirstPacket
                );

        ElnkSubmitCommandBlock(
                Adapter,
                CbIndex
                );

        Adapter->AlreadyProcessingStage = FALSE;

    } else {

        Adapter->AlreadyProcessingStage = FALSE;
        Adapter->StageOpen = FALSE;

        IF_LOG('P');

        return;

    }

    IF_LOG('P');

}
Exemplo n.º 11
0
NDIS_STATUS
ElnkSend(
    IN NDIS_HANDLE MacBindingHandle,
    IN PNDIS_PACKET Packet
    )

/*++

Routine Description:

    The ElnkSend request instructs a MAC to transmit a packet through
    the adapter onto the medium.

Arguments:

    MacBindingHandle - The context value returned by the MAC  when the
    adapter was opened.  In reality, it is a pointer to ELNK_OPEN.

    Packet - A pointer to a descriptor for the packet that is to be
    transmitted.

Return Value:
    The function value is the status of the operation.
--*/

{

    //
    // Holds the status that should be returned to the caller.
    //
    NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;

    //
    // Pointer to the adapter.
    //
    PELNK_ADAPTER Adapter;

    if ELNKDEBUG DPrint2("ElnkSend Packet = %x\n",Packet);

    Adapter = PELNK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
    NdisAcquireSpinLock(&Adapter->Lock);
    Adapter->References++;

    if (!Adapter->ResetInProgress) {

        PELNK_OPEN Open;

        Open = PELNK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);

        if (!Open->BindingShuttingDown) {

            UINT TotalPacketSize;

            //
            // Increment the references on the open while we are
            // accessing it in the interface.
            //

            Open->References++;

            NdisReleaseSpinLock(&Adapter->Lock);

            //
            // It is reasonable to do a quick check and fail if the packet
            // is larger than the maximum an ethernet can handle.
            //

            NdisQueryPacket(
                Packet,
                NULL,
                NULL,
                NULL,
                &TotalPacketSize
                );

            NdisAcquireSpinLock(&Adapter->Lock);

            if ((!TotalPacketSize) ||
                (TotalPacketSize > MAXIMUM_ETHERNET_PACKET_SIZE)) {
                Open->References--;
                StatusToReturn = NDIS_STATUS_RESOURCES;

            } else {

                PELNK_RESERVED Reserved = PELNK_RESERVED_FROM_PACKET(Packet);
                PNDIS_BUFFER FirstBuffer;
                PUCHAR BufferVA;
                UINT Length;

                //
                // Set Reserved->Loopback.
                //

                NdisQueryPacket(Packet, NULL, NULL, &FirstBuffer, NULL);

                //
                // Get VA of first buffer
                //

                NdisQueryBuffer(
                    FirstBuffer,
                    (PVOID *)&BufferVA,
                    &Length
                    );

                if (Open->ProtOptionFlags & NDIS_PROT_OPTION_NO_LOOPBACK){
                    Reserved->Loopback = FALSE;
                } else {
                    Reserved->Loopback = EthShouldAddressLoopBack(Adapter->FilterDB, BufferVA);
                }

                Reserved->MacBindingHandle = MacBindingHandle;

                //
                // Put on the stage queue.
                //

                if (!Adapter->LastStagePacket) {

                    Adapter->FirstStagePacket = Packet;

                } else {

                    PELNK_RESERVED_FROM_PACKET(Adapter->LastStagePacket)->Next = Packet;

                }

                Adapter->LastStagePacket = Packet;

                Reserved->Next = NULL;

                Adapter->TransmitsQueued++;

                //
                // Only try to push it through the stage queues
                // if somebody else isn't already doing it and
                // there is some hope of moving some packets
                // ahead.
                //

                while (!Adapter->AlreadyProcessingStage &&
                       Adapter->FirstStagePacket &&
                       Adapter->StageOpen
                      ) {

                    ElnkStagedAllocation(Adapter);

                }

            }

            //
            // We leave the reference for the pending send.
            //

        } else {

            StatusToReturn = NDIS_STATUS_CLOSING;

        }

    } else {

        StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;

    }

    ELNK_DO_DEFERRED(Adapter);
    return StatusToReturn;
}
Exemplo n.º 12
0
NDIS_STATUS
PtDeregisterDevice(
    VOID
    )
/*++

Routine Description:

    Deregister the ioctl interface. This is called whenever a miniport
    instance is halted. When the last miniport instance is halted, we
    request NDIS to delete the device object

Arguments:

    NdisDeviceHandle - Handle returned by NdisMRegisterDevice

Return Value:

    NDIS_STATUS_SUCCESS if everything worked ok

--*/
{
    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;

    DBGPRINT(("==>PassthruDeregisterDevice\n"));

    NdisAcquireSpinLock(&GlobalLock);

    ASSERT(MiniportCount > 0);

    --MiniportCount;
    
    if (0 == MiniportCount)
    {
        //
        // All miniport instances have been halted. Deregister
        // the control device.
        //

        ASSERT(ControlDeviceState == PS_DEVICE_STATE_READY);

        //
        // Block PtRegisterDevice() while we release the control
        // device lock and deregister the device.
        // 
        ControlDeviceState = PS_DEVICE_STATE_DELETING;

        NdisReleaseSpinLock(&GlobalLock);

        if (NdisDeviceHandle != NULL)
        {
            Status = NdisMDeregisterDevice(NdisDeviceHandle);
            NdisDeviceHandle = NULL;
        }

        NdisAcquireSpinLock(&GlobalLock);
        ControlDeviceState = PS_DEVICE_STATE_READY;
    }

    NdisReleaseSpinLock(&GlobalLock);

    DBGPRINT(("<== PassthruDeregisterDevice: %x\n", Status));
    return Status;
    
}
Exemplo n.º 13
0
NDIS_STATUS
PtRegisterDevice(
    VOID
    )
/*++

Routine Description:

    Register an ioctl interface - a device object to be used for this
    purpose is created by NDIS when we call NdisMRegisterDevice.

    This routine is called whenever a new miniport instance is
    initialized. However, we only create one global device object,
    when the first miniport instance is initialized. This routine
    handles potential race conditions with PtDeregisterDevice via
    the ControlDeviceState and MiniportCount variables.

    NOTE: do not call this from DriverEntry; it will prevent the driver
    from being unloaded (e.g. on uninstall).

Arguments:

    None

Return Value:

    NDIS_STATUS_SUCCESS if we successfully register a device object.

--*/
{
    NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         DeviceLinkUnicodeString;
    PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];

    DBGPRINT(("==>PtRegisterDevice\n"));

    NdisAcquireSpinLock(&GlobalLock);

    ++MiniportCount;
    
    if (1 == MiniportCount)
    {
        ASSERT(ControlDeviceState != PS_DEVICE_STATE_CREATING);

        //
        // Another thread could be running PtDeregisterDevice on
        // behalf of another miniport instance. If so, wait for
        // it to exit.
        //
        while (ControlDeviceState != PS_DEVICE_STATE_READY)
        {
            NdisReleaseSpinLock(&GlobalLock);
            NdisMSleep(1);
            NdisAcquireSpinLock(&GlobalLock);
        }

        ControlDeviceState = PS_DEVICE_STATE_CREATING;

        NdisReleaseSpinLock(&GlobalLock);

    
        NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));

        DispatchTable[IRP_MJ_CREATE] = NdisProtOpen;
        DispatchTable[IRP_MJ_CLEANUP] = NdisProtCleanup;
        DispatchTable[IRP_MJ_CLOSE] = NdisProtClose;
//	DispatchTable[IRP_MJ_READ]  = NdisProtRead;
	DispatchTable[IRP_MJ_READ]  = divert_read;
//	DispatchTable[IRP_MJ_WRITE] = PtDispatch;
	DispatchTable[IRP_MJ_WRITE] = divert_write;
//        DispatchTable[IRP_MJ_DEVICE_CONTROL] = NdisProtIoControl;
        DispatchTable[IRP_MJ_DEVICE_CONTROL] = PtDispatch;
        

        NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
        NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);

        //
        // Create a device object and register our dispatch handlers
        //
        
        Status = NdisMRegisterDevice(
                    NdisWrapperHandle, 
                    &DeviceName,
                    &DeviceLinkUnicodeString,
                    &DispatchTable[0],
                    &ControlDeviceObject,
                    &NdisDeviceHandle
                    );

        ControlDeviceObject->Flags |= DO_DIRECT_IO;

        NdisAcquireSpinLock(&GlobalLock);

        ControlDeviceState = PS_DEVICE_STATE_READY;
    }

    NdisReleaseSpinLock(&GlobalLock);

    DBGPRINT(("<==PtRegisterDevice: %x\n", Status));

    return (Status);
}
Exemplo n.º 14
0
MAC_TABLE_ENTRY *MacTableInsertEntry(
	IN RTMP_ADAPTER *pAd,
	IN UCHAR *pAddr,
	IN struct wifi_dev *wdev,
	IN UINT32 ent_type,
	IN UCHAR OpMode,
	IN BOOLEAN CleanAll)
{
	UCHAR HashIdx;
	int i, FirstWcid;
	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;

	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
		return NULL;

	FirstWcid = 1;


	/* allocate one MAC entry*/
	NdisAcquireSpinLock(&pAd->MacTabLock);
	for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++)   /* skip entry#0 so that "entry index == AID" for fast lookup*/
	{
		/* pick up the first available vacancy*/
		if (IS_ENTRY_NONE(&pAd->MacTab.Content[i]))
		{
			pEntry = &pAd->MacTab.Content[i];

			mac_entry_reset(pAd, pEntry, CleanAll);
			
			/* ENTRY PREEMPTION: initialize the entry */
			pEntry->wdev = wdev;
			pEntry->wcid = i;
			pEntry->func_tb_idx = wdev->func_idx;
			pEntry->bIAmBadAtheros = FALSE;
			pEntry->pAd = pAd;
			pEntry->CMTimerRunning = FALSE;

			COPY_MAC_ADDR(pEntry->Addr, pAddr);
			pEntry->Sst = SST_NOT_AUTH;
			pEntry->AuthState = AS_NOT_AUTH;
			pEntry->Aid = (USHORT)i;
			pEntry->CapabilityInfo = 0;
			pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
			
			pEntry->PsMode = PWR_ACTIVE;
			pEntry->NoDataIdleCount = 0;
			pEntry->ContinueTxFailCnt = 0;
#ifdef WDS_SUPPORT
			pEntry->LockEntryTx = FALSE;
#endif /* WDS_SUPPORT */
			pEntry->TimeStamp_toTxRing = 0;
			// TODO: shiang-usw,  remove upper setting becasue we need to migrate to tr_entry!
			pAd->MacTab.tr_entry[i].PsMode = PWR_ACTIVE;
			pAd->MacTab.tr_entry[i].NoDataIdleCount = 0;
			pAd->MacTab.tr_entry[i].ContinueTxFailCnt = 0;
			pAd->MacTab.tr_entry[i].LockEntryTx = FALSE;
			pAd->MacTab.tr_entry[i].TimeStamp_toTxRing = 0;
			pAd->MacTab.tr_entry[i].PsDeQWaitCnt = 0;

			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
			pEntry->GTKState = REKEY_NEGOTIATING;
			pEntry->PairwiseKey.KeyLen = 0;
			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
			pEntry->RSNIE_Len = 0;
			NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;

			do
			{

#ifdef CONFIG_AP_SUPPORT
#ifdef APCLI_SUPPORT
				if (ent_type == ENTRY_APCLI)
				{
					SET_ENTRY_APCLI(pEntry);
					//SET_ENTRY_AP(pEntry);//Carter, why set entry to APCLI then set to AP????
					COPY_MAC_ADDR(pEntry->bssid, pAddr);
					pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->func_tb_idx].wdev.AuthMode;
					pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->func_tb_idx].wdev.WepStatus;
					if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
					{
						pEntry->WpaState = AS_NOTUSE;
						pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
					}
					else
					{
						pEntry->WpaState = AS_PTKSTART;
						pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
					}
					break;
				}
#endif /* APCLI_SUPPORT */
#ifdef WDS_SUPPORT
				if (ent_type == ENTRY_WDS)
				{
					SET_ENTRY_WDS(pEntry);
					COPY_MAC_ADDR(pEntry->bssid, pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev.bssid);
					pEntry->AuthMode = Ndis802_11AuthModeOpen;
					pEntry->WepStatus = Ndis802_11EncryptionDisabled;
					break;
				}
#endif /* WDS_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */

#ifdef CONFIG_AP_SUPPORT
				if (ent_type == ENTRY_CLIENT)
				{	/* be a regular-entry*/
					if ((pEntry->func_tb_idx < pAd->ApCfg.BssidNum) &&
						(pEntry->func_tb_idx < MAX_MBSSID_NUM(pAd)) &&
						((pEntry->func_tb_idx < HW_BEACON_MAX_NUM)) &&
						(pAd->ApCfg.MBSSID[pEntry->func_tb_idx].MaxStaNum != 0) &&
						(pAd->ApCfg.MBSSID[pEntry->func_tb_idx].StaCount >= pAd->ApCfg.MBSSID[pEntry->func_tb_idx].MaxStaNum))
					{
						DBGPRINT(RT_DEBUG_WARN, ("%s: The connection table is full in ra%d.\n", __FUNCTION__, pEntry->func_tb_idx));
						NdisReleaseSpinLock(&pAd->MacTabLock);
						return NULL;
					}
					ASSERT((wdev == &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev));

					SET_ENTRY_CLIENT(pEntry);
					pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx];

					MBSS_MR_APIDX_SANITY_CHECK(pAd, pEntry->func_tb_idx);
					COPY_MAC_ADDR(pEntry->bssid, wdev->bssid);
					pEntry->AuthMode = wdev->AuthMode;
					pEntry->WepStatus = wdev->WepStatus;
					pEntry->GroupKeyWepStatus = wdev->GroupKeyWepStatus;

					if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
						pEntry->WpaState = AS_NOTUSE;
					else
						pEntry->WpaState = AS_INITIALIZE;

					pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
					pEntry->StaIdleTimeout = pAd->ApCfg.StaIdleTimeout;
					pAd->ApCfg.MBSSID[pEntry->func_tb_idx].StaCount++;
					pAd->ApCfg.EntryClientCount++;

					break;
				}
#endif /* CONFIG_AP_SUPPORT */

			} while (FALSE);

			tr_tb_set_entry(pAd, i, pEntry);
			
			RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE);


#ifdef CONFIG_AP_SUPPORT
			{
				if (IS_ENTRY_CLIENT(pEntry)) /* Only Client entry need the retry timer.*/
				{
					RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE);
#ifdef DOT11W_PMF_SUPPORT
					RTMPInitTimer(pAd, &pEntry->SAQueryTimer, GET_TIMER_FUNCTION(PMF_SAQueryTimeOut), pEntry, FALSE);
					RTMPInitTimer(pAd, &pEntry->SAQueryConfirmTimer, GET_TIMER_FUNCTION(PMF_SAQueryConfirmTimeOut), pEntry, FALSE);
#endif /* DOT11W_PMF_SUPPORT */
				}

#ifdef APCLI_SUPPORT
				if (IS_ENTRY_APCLI(pEntry))
					RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE);
#endif /* APCLI_SUPPORT */
			}
#endif /* CONFIG_AP_SUPPORT */



#ifdef STREAM_MODE_SUPPORT
			/* Enable Stream mode for first three entries in MAC table */

#endif /* STREAM_MODE_SUPPORT */

#ifdef UAPSD_SUPPORT
			/* Ralink WDS doesn't support any power saving.*/
			if (IS_ENTRY_CLIENT(pEntry)
			)
			{
				/* init U-APSD enhancement related parameters */
				UAPSD_MR_ENTRY_INIT(pEntry);
			}
#endif /* UAPSD_SUPPORT */

			pAd->MacTab.Size ++;

			/* Set the security mode of this entry as OPEN-NONE in ASIC */
			RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i);
#ifdef MT_MAC										
			if (pAd->chipCap.hif_type == HIF_MT)
				MT_ADDREMOVE_KEY(pAd, 1, pEntry->apidx, 0, pEntry->wcid, PAIRWISEKEYTABLE, &pEntry->PairwiseKey, pEntry->Addr);
#endif	

			/* Add this entry into ASIC RX WCID search table */
			RTMP_STA_ENTRY_ADD(pAd, pEntry);

#ifdef CONFIG_AP_SUPPORT
			IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
			{
#ifdef WSC_AP_SUPPORT
				pEntry->bWscCapable = FALSE;
				pEntry->Receive_EapolStart_EapRspId = 0;
#endif /* WSC_AP_SUPPORT */
			}
#endif /* CONFIG_AP_SUPPORT */

			DBGPRINT(RT_DEBUG_TRACE, ("%s(): alloc entry #%d, Total= %d\n",
						__FUNCTION__, i, pAd->MacTab.Size));
			break;
		}
	}
Exemplo n.º 15
0
VOID RTUSBWatchDog(IN RTMP_ADAPTER *pAd)
{
	PHT_TX_CONTEXT		pHTTXContext;
	int 					idx;
	ULONG				irqFlags;
	PURB		   		pUrb;
	BOOLEAN				needDumpSeq = FALSE;
	UINT32          	MACValue;

	if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))		
		return;
	
	idx = 0;
	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
	if ((MACValue & 0xff) !=0 )
	{
		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
		while((MACValue &0xff) != 0 && (idx++ < 10))
		{
		        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
		        RTMPusecDelay(1);
		}
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
	}

	idx = 0;
	if ((MACValue & 0xff00) !=0 )
	{
		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
		while((MACValue &0xff00) != 0 && (idx++ < 10))
		{
			RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
			RTMPusecDelay(1);
		}
		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
	}

	
	if (pAd->watchDogRxOverFlowCnt >= 2)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
									fRTMP_ADAPTER_BULKIN_RESET |
									fRTMP_ADAPTER_HALT_IN_PROGRESS |
									fRTMP_ADAPTER_NIC_NOT_EXIST))))
		{
			DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
			needDumpSeq = TRUE;
		}
		pAd->watchDogRxOverFlowCnt = 0;
	}


	for (idx = 0; idx < NUM_OF_TX_RING; idx++)
	{
		pUrb = NULL;
		
		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
		if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
		{
			pAd->watchDogTxPendingCnt[idx]++;

			if ((pAd->watchDogTxPendingCnt[idx] > 2) && 
				 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
				)
			{
				// FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
				pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
				if (pHTTXContext->IRPPending)
				{	// Check TxContext.
					pUrb = pHTTXContext->pUrb;
				}
				else if (idx == MGMTPIPEIDX)
				{
					PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
					
					//Check MgmtContext.
					pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
					pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
					pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
					
					if (pMLMEContext->IRPPending)
					{
						ASSERT(pMLMEContext->IRPPending);
						pUrb = pMLMEContext->pUrb;
					}
					else if (pNULLContext->IRPPending)
					{	
						ASSERT(pNULLContext->IRPPending);
						pUrb = pNULLContext->pUrb;
					}
					else if (pPsPollContext->IRPPending)
					{	
						ASSERT(pPsPollContext->IRPPending);
						pUrb = pPsPollContext->pUrb;
					}
				}
				
				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
				
				DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
				if (pUrb)
				{
					DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
					// unlink it now
					RTUSB_UNLINK_URB(pUrb);
					// Sleep 200 microseconds to give cancellation time to work
					RTMPusecDelay(200);
					needDumpSeq = TRUE;
				}
				else
				{
					DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
				}
			}
			else
			{
				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
			}
		}
		else
		{
			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
		}
	}

#ifdef DOT11_N_SUPPORT
	// For Sigma debug, dump the ba_reordering sequence.
	if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
	{
		USHORT				Idx;
		PBA_REC_ENTRY		pBAEntry = NULL;
		UCHAR				count = 0;
		struct reordering_mpdu *mpdu_blk;
					
		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];

		pBAEntry = &pAd->BATable.BARecEntry[Idx];
		if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
		{
			DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
			mpdu_blk = pBAEntry->list.next;
			while (mpdu_blk)
			{
				DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
				mpdu_blk = mpdu_blk->next;
				count++;
			}

			DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
		}
	}
#endif // DOT11_N_SUPPORT //
}
Exemplo n.º 16
0
Boolean __fastcall
ssh_interceptor_iodevice_create_device(SshInterceptorIoDevice io_dev)
{
  SshInterceptor interceptor;
  PDRIVER_OBJECT driver;
  PSECURITY_DESCRIPTOR new_sd;
  PDRIVER_DISPATCH *fn_table;
  NTSTATUS st;
#ifndef SSH_IM_INTERCEPTOR 
  PDEVICE_OBJECT device;
#else
  PDRIVER_DISPATCH major_function[IRP_MJ_MAXIMUM_FUNCTION + 1];
#endif /* SSH_IM_INTERCEPTOR */

  SSH_ASSERT(io_dev != NULL);  
  SSH_ASSERT(io_dev->interceptor != NULL);
  interceptor = io_dev->interceptor;
  SSH_ASSERT(interceptor->driver_object != NULL);
  driver = interceptor->driver_object;

  NdisAcquireSpinLock(&io_dev->output_queue_lock);
  if (io_dev->destroy_after_close)
    {
      SSH_DEBUG(SSH_D_NICETOKNOW, ("Clearing delayed destroy flag..."));
      io_dev->destroy_after_close = FALSE;
    }
  NdisReleaseSpinLock(&io_dev->output_queue_lock);

  if (InterlockedCompareExchange(&io_dev->io_device_created, 1, 0) != 0)
    {
      SSH_DEBUG(SSH_D_HIGHSTART, 
                ("I/O device already exists; ignoring this call"));
      return TRUE;
    }

  SSH_DEBUG(SSH_D_HIGHSTART, ("Creating I/O device and symbolic link..."));

#ifndef SSH_IM_INTERCEPTOR
#pragma warning(disable : 28175)
  fn_table = driver->MajorFunction;
#pragma warning(default : 28175)
#else
  memset(&major_function, 0, sizeof(major_function));
  fn_table = major_function;
#endif /* SSH_IM_INTERCEPTOR */

  /* Create the I/O device and symbolic link and limit the access permissions
     of the I/O device. */
  /* Initialize dispatch function table */
  fn_table[IRP_MJ_CREATE] = ssh_interceptor_iodevice_dispatch_create;
  fn_table[IRP_MJ_CLOSE] = ssh_interceptor_iodevice_dispatch_close;
  fn_table[IRP_MJ_CLEANUP] = ssh_interceptor_iodevice_dispatch_cleanup;
  fn_table[IRP_MJ_READ] = ssh_interceptor_iodevice_dispatch_read;
  fn_table[IRP_MJ_WRITE] = ssh_interceptor_iodevice_dispatch_write;
  fn_table[IRP_MJ_DEVICE_CONTROL] = ssh_interceptor_iodevice_dispatch_ioctl;

#ifdef SSH_IM_INTERCEPTOR
  /* Try to register our I/O device with NDIS */
  st = NdisMRegisterDevice(io_dev->interceptor->wrapper_handle,
                           &io_dev->device_name, 
                           &io_dev->symlink_name,
                           fn_table, 
                           &io_dev->device, 
                           &io_dev->handle);
  if (!NT_SUCCESS(st))
    {
      SSH_DEBUG(SSH_D_FAIL, ("NdisMRegisterDevice() failed - %08x", st));
      return FALSE;
    }
#else /* not SSH_IM_INTERCEPTOR */
  st = IoCreateDevice(driver, sizeof(void *), 
                      &io_dev->device_name,
                      FILE_DEVICE_NETWORK, 0, 
                      (BOOLEAN)io_dev->exclusive_access, 
                      &device);
  if (!NT_SUCCESS(st))
    {
      SSH_DEBUG(SSH_D_FAIL, ("IoCreateDevice() failed - %08x", st));
      return FALSE;
    }

  io_dev->device = device;
  *((SshInterceptorIoDevice *)device->DeviceExtension) = io_dev;
#endif /* not SSH_IM_INTERCEPTOR */

  io_dev->device->AlignmentRequirement = FILE_QUAD_ALIGNMENT;
  io_dev->device->Flags |= DO_DIRECT_IO;

  /* Remove world access to newly created device object */
#pragma warning(disable : 28175)
  if (ssh_access_permissions_limit(io_dev->device->SecurityDescriptor,
                                   &new_sd) != FALSE)
    {
      io_dev->orig_sd = io_dev->device->SecurityDescriptor;
      io_dev->device->SecurityDescriptor = new_sd;
    }
  else
    {
      SSH_DEBUG(SSH_D_FAIL, ("ssh_access_permissions_limit() failed!"));
    }
#pragma warning(default : 28175)

#ifndef SSH_IM_INTERCEPTOR
  /* Create symbolic link to make device accessible from Win32 */
  st = IoCreateSymbolicLink(&io_dev->symlink_name, 
                            &io_dev->device_name);
  if (!NT_SUCCESS(st))
    {
      SSH_DEBUG(SSH_D_FAIL,
                ("IoCreateSymbolicLink() failed (%08X): %ls -> %ls",
                 st, 
                 io_dev->symlink_name.Buffer, 
                 io_dev->device_name.Buffer));

      IoDeleteDevice(io_dev->device);
      return FALSE;
    }
#endif /* SSH_IM_INTERCEPTOR */

  return TRUE;
}
Exemplo n.º 17
0
/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:
	
	IRQL = 
	
	Note:
	
	========================================================================
*/
NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
	IN	PRTMP_ADAPTER	pAd,
	IN	NDIS_OID		Oid,
	IN	BOOLEAN			SetInformation,
	IN	PVOID			pInformationBuffer,
	IN	UINT32			InformationBufferLength)
{
	NDIS_STATUS	status;
	PCmdQElmt	cmdqelmt = NULL;
	RTMP_OS_TASK	*pTask = &pAd->cmdQTask;
	
#ifdef KTHREAD_SUPPORT
	if (pTask->kthread_task == NULL)
#else
	CHECK_PID_LEGALITY(pTask->taskPID) 
		;
	else
#endif
		return (NDIS_STATUS_RESOURCES);

	status = os_alloc_mem(pAd, (PUCHAR *)(&cmdqelmt), sizeof(CmdQElmt));
	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
		return (NDIS_STATUS_RESOURCES);

		cmdqelmt->buffer = NULL;
		if (pInformationBuffer != NULL)
		{	
			status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength);
			if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
			{       
				kfree(cmdqelmt);
				return (NDIS_STATUS_RESOURCES);
			}
			else
			{
				NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
				cmdqelmt->bufferlength = InformationBufferLength;
			}
		}
		else
			cmdqelmt->bufferlength = 0;
	
	cmdqelmt->command = Oid;
	cmdqelmt->CmdFromNdis = TRUE;
	if (SetInformation == TRUE)
		cmdqelmt->SetOperation = TRUE;
	else
		cmdqelmt->SetOperation = FALSE;

	NdisAcquireSpinLock(&pAd->CmdQLock);
	if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT)
	{
		EnqueueCmd((&pAd->CmdQ), cmdqelmt);
		status = NDIS_STATUS_SUCCESS;
	}
	else
	{
		status = NDIS_STATUS_FAILURE;
	}
	NdisReleaseSpinLock(&pAd->CmdQLock);
	
	if (status == NDIS_STATUS_FAILURE)
	{
		if (cmdqelmt->buffer)
			os_free_mem(pAd, cmdqelmt->buffer);
		os_free_mem(pAd, cmdqelmt);
	}
	else
	RTCMDUp(pAd);


    return(NDIS_STATUS_SUCCESS);
}
Exemplo n.º 18
0
Boolean
ssh_interceptor_iodevice_send(SshInterceptorIoDevice io_dev,
                              unsigned len,
                              unsigned char *addr,
                              Boolean reliable)
{
  SshDeviceBuffer buf = NULL;
  Boolean st = FALSE;


  SSH_ASSERT(addr != NULL); /* Check that we have a valid packet */
  SSH_ASSERT(len > 0);
  SSH_ASSERT(len <= 0x7FFFFFFF); /* Our length field is "only" 31 bits long */

  /* No need to use spin lock (yet), because nothing bad happens if the I/O 
     device will be closed between this check and the moment when we acquire 
     an output queue spin lock. */
  if (InterlockedCompareExchange(&io_dev->opened_instances, 0, 0) != 0)
    buf = ssh_iodevice_buffer_alloc(io_dev, reliable);

  if (buf)
    {
      buf->len = len;
      buf->addr = addr;
      buf->offset = 0;
      if (reliable)
        buf->reliable = 1;
      else
        buf->reliable = 0;

      NdisAcquireSpinLock(&io_dev->output_queue_lock);
      /* This time it's important that we read correct value from
         'io_dev->open', so we must protect also this check with a
         spin lock */
      if (InterlockedCompareExchange(&io_dev->opened_instances, 0, 0) != 0)
        {
          InsertTailList(&io_dev->output_queue, &buf->link);

          if (reliable == FALSE)
            InsertTailList(&io_dev->unreliable_output_queue,
                           &buf->unreliable_list_link);

          /* Notify the worker thread */
          ssh_task_notify(&io_dev->worker_thread, SSH_TASK_SIGNAL_NOTIFY);

          st = TRUE;
        }
      NdisReleaseSpinLock(&io_dev->output_queue_lock);
    }

  if (st != TRUE)
    {
      ssh_free(addr);

      if (buf != NULL)
        {
          buf->addr = NULL;
          ssh_iodevice_buffer_free(io_dev, buf);
        }
    }

  return st;
}
Exemplo n.º 19
0
/*
	========================================================================

	Routine Description:
		Process MGMT ring DMA done interrupt, running in DPC level

	Arguments:
		pAd 	Pointer to our adapter

	Return Value:
		None

	IRQL = DISPATCH_LEVEL
	
	Note:

	========================================================================
*/
VOID	RTMPHandleMgmtRingDmaDoneInterrupt(
	IN	PRTMP_ADAPTER	pAd)
{
	PTXD_STRUC	 pTxD;
#ifdef RT_BIG_ENDIAN
    PTXD_STRUC      pDestTxD;
    TXD_STRUC       TxD;
#endif
	PNDIS_PACKET pPacket;
/*	int 		 i;*/
	UCHAR	FREE = 0;
	PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
	UINT8 TXWISize = pAd->chipCap.TXWISize;

	NdisAcquireSpinLock(&pAd->MgmtRingLock);

	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
	while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
	{
		FREE++;
#ifdef RT_BIG_ENDIAN
        pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
        TxD = *pDestTxD;
        pTxD = &TxD;
		RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
#else
		pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
#endif
/*		pTxD->DMADONE = 0; */
		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;

		if (pPacket == NULL)
		{
			INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
			continue;
		}

#define LMR_FRAME_GET()	(GET_OS_PKT_DATAPTR(pPacket) + TXWISize)

#ifdef UAPSD_SUPPORT
#ifdef CONFIG_AP_SUPPORT
		IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
		{
			UAPSD_QoSNullTxMgmtTxDoneHandle(pAd,
					pPacket,
					LMR_FRAME_GET());
		}
#endif /* CONFIG_AP_SUPPORT */
#endif /* UAPSD_SUPPORT */

#ifdef CONFIG_AP_SUPPORT
#endif /* CONFIG_AP_SUPPORT */

		if (pPacket)
		{
			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, RTMP_PCI_DMA_TODEVICE);
			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
		}
		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;

		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
		if (pPacket)
		{
			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, RTMP_PCI_DMA_TODEVICE);
			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
		}
		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;

		/* flush dcache if no consistent memory is supported */
		RTMP_DCACHE_FLUSH(pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocPa,
						RXD_SIZE);

		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);

#ifdef RT_BIG_ENDIAN
        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
        WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD);
#endif
	}
	NdisReleaseSpinLock(&pAd->MgmtRingLock);

}
Exemplo n.º 20
0
void 
ssh_interceptor_iodevice_complete_ioctl(SshInterceptorIoDevice iodevice,
                                        SshIoctlRequest ioctl_req,
                                        SshIoctlStatus status)
{
  SshIoDeviceIoctlRequest ioctl;
  SshIoDeviceIoctlHandler handler;
  PIRP irp;

  SSH_ASSERT(iodevice != NULL);
  SSH_ASSERT(ioctl_req != NULL);
  SSH_ASSERT(ioctl_req->device == iodevice);

  ioctl = CONTAINING_RECORD(ioctl_req, 
                            SshIoDeviceIoctlRequestStruct, 
                            public_data);

  NdisAcquireSpinLock(&iodevice->ioctl_req_list_lock);
  RemoveEntryList(&ioctl->private_data.link);
  NdisReleaseSpinLock(&iodevice->ioctl_req_list_lock);

  handler = ioctl->public_data.context;

  irp = ioctl->private_data.irp;






#pragma warning(disable: 4311 4312)
  IoSetCancelRoutine(irp, NULL);
#pragma warning(default: 4311 4312)

  switch (status)
    {
    case SSH_IOCTL_RESULT_SUCCESS:
      irp->IoStatus.Status = STATUS_SUCCESS;

      irp->IoStatus.Information = ioctl->public_data.bytes_written;
      IoCompleteRequest(irp, IO_NO_INCREMENT);
      break;

    case SSH_IOCTL_RESULT_FAILURE:
      irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
      irp->IoStatus.Information = 0;
      IoCompleteRequest(irp, IO_NO_INCREMENT);
      break;

    case SSH_IOCTL_RESULT_CANCELLED:
      irp->IoStatus.Status = STATUS_CANCELLED;
      irp->IoStatus.Information = 0;
      IoCompleteRequest(irp, IO_NO_INCREMENT);
      break;

    default:
      SSH_NOTREACHED;
      break;
    }

  InterlockedDecrement(&handler->ref_count);




  ssh_free(ioctl);
}
Exemplo n.º 21
0
VOID RTMPInsertRepeaterEntry(
	IN PRTMP_ADAPTER pAd,
	IN UCHAR apidx,
	IN PUCHAR pAddr)
{
	INT CliIdx, idx;
	UCHAR HashIdx;
	BOOLEAN Cancelled;
	UCHAR tempMAC[MAC_ADDR_LEN];
	APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
	PREPEATER_CLIENT_ENTRY pReptCliEntry = NULL, pCurrEntry = NULL;
	PREPEATER_CLIENT_ENTRY_MAP pReptCliMap;
	UCHAR SPEC_ADDR[6][3] = {{0x02, 0x0F, 0xB5}, {0x02, 0x09, 0x5B},
								{0x02, 0x14, 0x6C}, {0x02, 0x18, 0x4D},
								{0x02, 0x1B, 0x2F}, {0x02, 0x1E, 0x2A}};
	MAC_TABLE_ENTRY *pMacEntry = NULL;

	DBGPRINT(RT_DEBUG_TRACE, (" %s.\n", __FUNCTION__));

       pMacEntry = MacTableLookup(pAd, pAddr);
       if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry))
       {
               if (pMacEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
               {
                       DBGPRINT(RT_DEBUG_ERROR, (" wireless client is not ready !!!\n"));
                       return;
               }
       }

	NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock);

	if (pAd->ApCfg.RepeaterCliSize >= MAX_EXT_MAC_ADDR_SIZE)
	{
		DBGPRINT(RT_DEBUG_ERROR, (" Repeater Client Full !!!\n"));
		NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);
		return ;
	}

	for (CliIdx = 0; CliIdx < MAX_EXT_MAC_ADDR_SIZE; CliIdx++)
	{
		pReptCliEntry = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[CliIdx];

		if ((pReptCliEntry->CliEnable) && 
			(MAC_ADDR_EQUAL(pReptCliEntry->OriginalAddress, pAddr) || MAC_ADDR_EQUAL(pReptCliEntry->CurrentAddress, pAddr)))
		{
			DBGPRINT(RT_DEBUG_ERROR, ("\n  receive mac :%02x:%02x:%02x:%02x:%02x:%02x !!!\n", 
						pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]));
			DBGPRINT(RT_DEBUG_ERROR, (" duplicate Insert !!!\n"));
			NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);
			return ;
		}

		if (pReptCliEntry->CliEnable == FALSE)
			break;
	}

	if (CliIdx >= MAX_EXT_MAC_ADDR_SIZE)
	{
		DBGPRINT(RT_DEBUG_ERROR, (" Repeater Client Full !!!\n"));
		NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);
		return ;
	}

	pReptCliEntry = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[CliIdx];
	pReptCliMap = &pAd->ApCfg.ApCliTab[apidx].RepeaterCliMap[CliIdx];

	/* ENTRY PREEMPTION: initialize the entry */
	RTMPCancelTimer(&pReptCliEntry->ApCliAuthTimer, &Cancelled);
	RTMPCancelTimer(&pReptCliEntry->ApCliAssocTimer, &Cancelled);
	pReptCliEntry->CtrlCurrState = APCLI_CTRL_DISCONNECTED;
	pReptCliEntry->AuthCurrState = APCLI_AUTH_REQ_IDLE;
	pReptCliEntry->AssocCurrState = APCLI_ASSOC_IDLE;
	pReptCliEntry->CliConnectState = 0;
	pReptCliEntry->CliValid = FALSE;
	pReptCliEntry->bEthCli = FALSE;
	pReptCliEntry->MacTabWCID = 0xFF;
	pReptCliEntry->AuthReqCnt = 0;
	pReptCliEntry->AssocReqCnt = 0;
	pReptCliEntry->CliTriggerTime = 0;
	pReptCliEntry->pNext = NULL;
	pReptCliMap->pReptCliEntry = pReptCliEntry;
	pReptCliMap->pNext = NULL;

	COPY_MAC_ADDR(pReptCliEntry->OriginalAddress, pAddr);
	COPY_MAC_ADDR(tempMAC, pAddr);
#ifdef SMART_MESH
	NdisZeroMemory(pAd->vMacAddrPrefix,sizeof(pAd->vMacAddrPrefix));
#endif /* SMART_MESH */

	if (pAd->ApCfg.MACRepeaterOuiMode == 1)
	{
		DBGPRINT(RT_DEBUG_ERROR, (" todo !!!\n"));
	}
	else if (pAd->ApCfg.MACRepeaterOuiMode == 2)
	{
		INT IdxToUse;
		
		for (idx = 0; idx < 6; idx++)
		{
			if (RTMPEqualMemory(SPEC_ADDR[idx], pAddr, 3))
				break;
		}

		/* If there is a matched one, use the next one; otherwise, use the first one. */
		if (idx >= 0  && idx < 5)
			IdxToUse = idx + 1;
		else 
			IdxToUse = 0;
		NdisCopyMemory(tempMAC, SPEC_ADDR[IdxToUse], 3);
#ifdef SMART_MESH
		INT vMacIdx;
		if (IdxToUse >= 0  && IdxToUse < 5)
			vMacIdx = IdxToUse + 1;
		else
			vMacIdx = 0;
		
		NdisCopyMemory(pAd->vMacAddrPrefix, SPEC_ADDR[vMacIdx], sizeof(pAd->vMacAddrPrefix));
#endif /* SMART_MESH */
	}
	else
	{
		NdisCopyMemory(tempMAC, pAd->ApCfg.ApCliTab[apidx].wdev.if_addr, 3);
	}

	COPY_MAC_ADDR(pReptCliEntry->CurrentAddress, tempMAC);
	pReptCliEntry->CliEnable = TRUE;
	pReptCliEntry->CliConnectState = 1;
	pReptCliEntry->pNext = NULL;
	NdisGetSystemUpTime(&pReptCliEntry->CliTriggerTime);

	RTMPInsertRepeaterAsicEntry(pAd, CliIdx, tempMAC);
		
	HashIdx = MAC_ADDR_HASH_INDEX(tempMAC);
	if (pAd->ApCfg.ReptCliHash[HashIdx] == NULL)
	{
		pAd->ApCfg.ReptCliHash[HashIdx] = pReptCliEntry;
	}
	else
	{
		pCurrEntry = pAd->ApCfg.ReptCliHash[HashIdx];
		while (pCurrEntry->pNext != NULL)
			pCurrEntry = pCurrEntry->pNext;
		pCurrEntry->pNext = pReptCliEntry;
	}

	HashIdx = MAC_ADDR_HASH_INDEX(pReptCliEntry->OriginalAddress);
	if (pAd->ApCfg.ReptMapHash[HashIdx] == NULL)
		pAd->ApCfg.ReptMapHash[HashIdx] = pReptCliMap;
	else
	{
		PREPEATER_CLIENT_ENTRY_MAP pCurrMapEntry;
	
		pCurrMapEntry = pAd->ApCfg.ReptMapHash[HashIdx];

		while (pCurrMapEntry->pNext != NULL)
			pCurrMapEntry = pCurrMapEntry->pNext;
		pCurrMapEntry->pNext = pReptCliMap;
	}

	pAd->ApCfg.RepeaterCliSize++;
	NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);

	NdisZeroMemory(&ApCliCtrlMsg, sizeof(APCLI_CTRL_MSG_STRUCT));
	ApCliCtrlMsg.Status = MLME_SUCCESS;
	COPY_MAC_ADDR(&ApCliCtrlMsg.SrcAddr[0], tempMAC);
	ApCliCtrlMsg.BssIdx = apidx;
	ApCliCtrlMsg.CliIdx = CliIdx;

	MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_MT2_AUTH_REQ,
			sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, apidx);

}
Exemplo n.º 22
0
/* main handler, called when data arrives at bchannels */
VOID
mtl__rx_bchan_handler
	(
	MTL_CHAN	*chan,
	USHORT 		bchan,
	ULONG		IddRxFrameType,
	IDD_XMSG 	*msg
	)
{
    MTL         *mtl;
    MTL_HDR     hdr;
    MTL_AS      *as;
	USHORT		FragmentFlags, CopyLen;
	MTL_RX_TBL	*RxTable;
    D_LOG(D_ENTRY, ("mtl__rx_bchan_handler: chan: 0x%p, bchan: %d, msg: 0x%p", chan, bchan, msg));

    /* assigned mtl using back pointer */
    mtl = chan->mtl;

	//
	// acquire the lock fot this mtl
	//
	NdisAcquireSpinLock(&mtl->lock);

    /* if not connected, ignore */
    if ( !mtl->is_conn )
    {
        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: packet on non connected mtl, ignored"));
		goto exit_code;
    }

	RxTable = &mtl->rx_tbl;
    D_LOG(D_ENTRY, ("mtl__rx_bchan_handler: mtl: 0x%p, buflen: %d, bufptr: 0x%p", \
                                                            mtl, msg->buflen, msg->bufptr));
	//
	// if we are in detect mode
	//
	if (!mtl->RecvFramingBits)
	{
		UCHAR	DetectData[3];

		/* extract header, check for fields */
		IddGetDataFromAdapter(chan->idd,
		                      (PUCHAR)&hdr,
							  (PUCHAR)msg->bufptr,
							  sizeof(MTL_HDR));

//		NdisMoveMemory ((PUCHAR)&hdr, (PUCHAR)msg->bufptr, sizeof(MTL_HDR));

		//
		// this is used for inband signalling - ignore it
		//
		if (hdr.sig_tot == 0x50)
			goto exit_code;

		//
		// if this is dkf we need offset of zero for detection to work
		//
		if ( ((hdr.sig_tot & 0xF0) == 0x50) && (hdr.ofs != 0) )
			goto exit_code;

		//
		// extract some data from the frame
		//
		IddGetDataFromAdapter(chan->idd,
		                      (PUCHAR)&DetectData,
							  (PUCHAR)&msg->bufptr[4],
							  2);

//		NdisMoveMemory((PUCHAR)&DetectData, (PUCHAR)&msg->bufptr[4], 2);
	
		D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: hdr: 0x%x 0x%x 0x%x", hdr.sig_tot, \
																	 hdr.seq, hdr.ofs));

		D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: DetectData: 0x%x 0x%x", DetectData[0], DetectData[1]));

		if ( (IddRxFrameType & IDD_FRAME_PPP) ||
			((IddRxFrameType & IDD_FRAME_DKF) &&
			   ((DetectData[0] == 0xFF) && (DetectData[1] == 0x03))))
		{
			mtl->RecvFramingBits = PPP_FRAMING;
			mtl->SendFramingBits = PPP_FRAMING;
			RxTable->NextFree = 0;
		}
		else
		{
			mtl->RecvFramingBits = RAS_FRAMING;
			mtl->SendFramingBits = RAS_FRAMING;
		}

        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Deteced WrapperFrameType: 0x%x", mtl->RecvFramingBits));

		//
		// don't pass up detected frame for now
		//
		goto exit_code;
	}

	if (IddRxFrameType & IDD_FRAME_DKF)
	{
        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Received IddFrameType: DKF"));

		/* size of packet has to be atleast as size of header */
		if ( msg->buflen < sizeof(hdr) )
		{
			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: packet size too small, ignored"));
			RxTable->DKFReceiveError1++;
			goto exit_code;
		}
	
		/* extract header, check for fields */
		IddGetDataFromAdapter(chan->idd,
		                      (PUCHAR)&hdr,
							  (PUCHAR)msg->bufptr,
							  sizeof(MTL_HDR));

		D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: hdr: 0x%x 0x%x 0x%x", hdr.sig_tot, \
																	 hdr.seq, hdr.ofs));

		//
		// if this is not our header of if this is an inband uus
		// ignore it
		//
		if ( (hdr.sig_tot & 0xF0) != 0x50 || hdr.sig_tot == 0x50)
		{
			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: bad header signature, ignored"));
			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, [0]: 0x%x", mtl, hdr.sig_tot));
			RxTable->DKFReceiveError2++;
			goto exit_code;
		}
	
		if ( (hdr.ofs >= MTL_MAC_MTU) || ((hdr.ofs + msg->buflen - sizeof(hdr)) > MTL_MAC_MTU) )
		{
			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: bad offset/buflen, ignored"));
			D_LOG(D_ALWAYS, ("mtl: 0x%p, Offset: %d, BufferLength: %d", mtl, hdr.ofs, msg->buflen));
			RxTable->DKFReceiveError3++;
			goto exit_code;
		}
	
		NdisAcquireSpinLock(&RxTable->lock);

		/* build pointer to assembly descriptor & lock it */
		as = RxTable->as_tbl + (hdr.seq % MTL_RX_BUFS);

		//
		// if this assembly pointer is not free (queued) then
		// just drop this fragment
		//
		if (as->Queued)
		{
			D_LOG(D_ALWAYS, ("DKFRx: AssemblyQueue Overrun! mtl: 0x%p, as: 0x%p, seq: %d", \
			         mtl, as, hdr.seq));

			RxTable->DKFReceiveError4++;
			as->QueueOverRun++;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}
	
		/* check for new slot */
		if ( !as->tot )
		{
			new_slot:
	
			/* new entry, fill-up */
			as->seq = hdr.seq;              /* record sequence number */
			as->num = 1;                    /* just received 1'st fragment */
			as->ttl = 1000;                 /* time to live init val */
			as->len = msg->buflen - sizeof(hdr); /* record received length */
			as->tot = hdr.sig_tot & 0x0F;   /* record number of expected fragments */
	
			/* copy received data into buffer */
			copy_data:
			IddGetDataFromAdapter(chan->idd,
			                      (PUCHAR)as->buf + hdr.ofs,
								  (PUCHAR)msg->bufptr + sizeof(hdr),
								  (USHORT)(msg->buflen - sizeof(hdr)));
//			NdisMoveMemory (as->buf + hdr.ofs, msg->bufptr + sizeof(hdr), msg->buflen - sizeof(hdr));
		}
		else if ( as->seq == hdr.seq )
		{
			/* same_seq: */
	
			/* same sequence number, accumulate */
			as->num++;
			as->len += (msg->buflen - sizeof(hdr));
	
			goto copy_data;
		}
		else
		{
			/* bad_frag: */
	
			/*
			* if this case, an already taken slot is hit, but with a different
			* sequence number. this indicates a wrap-around in as_tbl. prev
			* entry is freed and then this fragment is recorded as first
			*/
			D_LOG(D_ALWAYS, ("DKFRx: Bad Fragment! mtl: 0x%p, as: 0x%p, as->seq: %d, seq: %d", \
			         mtl, as, as->seq, hdr.seq));

			D_LOG(D_ALWAYS, ("as->tot: %d, as->num: %d", as->tot, as->num));

			RxTable->DKFReceiveError5++;
			goto new_slot;
		}
	
		/* if all fragments recieved for packet, time to mail it up */
		if ( as->tot == as->num )
		{
			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: pkt mailed up, buf: 0x%p, len: 0x%x", \
												as->buf, as->len));

			QueueDescriptorForRxIndication(mtl, as);

			//
			// mark this guy as being queued
			//
			as->Queued = 1;
		}
	
		/* release assembly descriptor */
		NdisReleaseSpinLock(&RxTable->lock);
	}
	else if (IddRxFrameType & IDD_FRAME_PPP)
	{
        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Received IddFrameType: PPP"));

		NdisAcquireSpinLock(&RxTable->lock);

		/* build pointer to assembly descriptor & lock it */
		as = RxTable->as_tbl + (RxTable->NextFree % MTL_RX_BUFS);

		//
		// if this assembly pointer is not free (queued) then
		// just drop this fragment
		//
		if (as->Queued)
		{
			D_LOG(D_ALWAYS, ("PPPRx: AssemblyQueue Overrun! mtl: 0x%p, as: 0x%p, NextFree: %d", \
			         mtl, as, RxTable->NextFree));

			as->QueueOverRun++;

			RxTable->PPPReceiveError1++;

			NdisReleaseSpinLock(&RxTable->lock);

			goto exit_code;
		}

		FragmentFlags = msg->FragmentFlags;

        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: FragmentFlags: 0x%x, CurrentRxState: 0x%x", FragmentFlags, as->State));

		switch (as->State)
		{
			case RX_MIDDLE:
				if (FragmentFlags & H_RX_N_BEG)
					break;

				as->MissCount++;

				//
				// missed an end buffer
				//
				D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, Miss in State: %d, FragmentFlags: 0x%x, MissCount: %d", \
				              mtl, as->State, FragmentFlags, as->MissCount));

				RxTable->PPPReceiveError2++;

				goto clearbuffer;

				break;

			case RX_BEGIN:
			case RX_END:
				if (FragmentFlags & H_RX_N_BEG)
				{
					//
					// missed a begining buffer
					//
					as->MissCount++;

					D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, Miss in State: %d, FragmentFlags: 0x%x, MissCount: %d", \
				              mtl, as->State, FragmentFlags, as->MissCount));

					RxTable->PPPReceiveError3++;

					goto done;
				}
clearbuffer:
				//
				// clear rx buffer
				//
				NdisZeroMemory(as->buf, sizeof(as->buf));

				//
				// start data at begin of buffer
				//
				as->DataPtr = as->buf;

				//
				// new buffer
				//
				as->len = 0;

				//
				// set rx state
				//
				as->State = RX_MIDDLE;

				//
				// set time to live
				//
				as->ttl = 1000;

				//
				// there is always only one fragment with PPP
				// maybe a big one but still only one
				//
				as->tot = 1;

				break;

			default:
				D_LOG(D_ALWAYS, ("Invalid PPP Rx State! mtl: 0x%p, as: 0x%p State: 0x%x", \
				          mtl, as, as->State));

				as->State = RX_BEGIN;

				as->tot = 0;

				as->MissCount++;

				goto done;

				break;
		}

		//
		// get the length to be copy
		//
		CopyLen = msg->buflen;


        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: CopyLen: %d", CopyLen));

		if (FragmentFlags & H_RX_N_END)
		{
			//
			// if this is not the last buffer and length is 0
			// we are done
			//
			if (CopyLen == 0)
				goto done_copy;

		}
		else
		{
			//
			// if CopyLen = 0 buffer only contains 2 CRC bytes
			//
			if (CopyLen == 0)
			{
				goto done_copy;
			}

			//
			// buffer contains only 1 CRC byte
			//
			else if (CopyLen == (-1 & H_RX_LEN_MASK))
			{
				//
				// previous buffer had a crc byte in it so remove it
				//
				as->len -= 1;
				goto done_copy;
			}

			//
			// buffer contains no crc or data bytes
			//
			else if (CopyLen == (-2 & H_RX_LEN_MASK))
			{
				//
				// previous buffer had 2 crc bytes in it so remove them
				//
				as->len -= 2;
				goto done_copy;
			}

		}

		//
		// if larger than max rx size throw away
		//
		if (CopyLen > IDP_MAX_RX_LEN)
		{
			//
			// buffer to big so dump it
			//
			as->State = RX_BEGIN;

			as->MissCount++;

			RxTable->PPPReceiveError4++;

			/* mark as free now */
			as->tot = 0;

			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, RxToLarge: RxSize: %d, MissCount: %d", mtl, CopyLen, as->MissCount));
			goto done;
		}

		as->len += CopyLen;

		if (as->len > MTL_MAC_MTU)
		{
			//
			// Frame is to big so dump it
			//
			as->State = RX_BEGIN;

			RxTable->PPPReceiveError5++;

			as->MissCount++;

			/* mark as free now */
			as->tot = 0;

			D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: AssembledRxToLarge: mtl: 0x%p, AsRxSize: %d, MissCount: %d", mtl, as->len, as->MissCount));
			goto done;
		}

		//
		// copy the data to rx descriptor
		//
		IddGetDataFromAdapter(chan->idd,
		                      (PUCHAR)as->DataPtr,
							  (PUCHAR)msg->bufptr,
							  CopyLen);
//		NdisMoveMemory(as->DataPtr, msg->bufptr, CopyLen);

		//
		// update data ptr
		//
		as->DataPtr += CopyLen;


done_copy:
		if (!(FragmentFlags & H_RX_N_END))
		{
			//
			// if this is the end of the frame indicate to wrapper
			//
			as->State = RX_END;

			RxTable->NextFree++;

			QueueDescriptorForRxIndication(mtl, as);

			//
			// mark this guy as being queued
			//
			as->Queued = 1;
		}

done:
		/* release assembly descriptor */
		NdisReleaseSpinLock(&RxTable->lock);
	}
	else
        D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Received IddFrameType: ??????!!!!!!"));

	//
	// exit code
	// release spinlock and return
	//
    exit_code:

	NdisReleaseSpinLock(&mtl->lock);
}
Exemplo n.º 23
0
VOID RTMPRemoveRepeaterEntry(
	IN PRTMP_ADAPTER pAd,
	IN UCHAR apIdx,
	IN UCHAR CliIdx)
{
	USHORT HashIdx;
	REPEATER_CLIENT_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
	REPEATER_CLIENT_ENTRY_MAP *pMapEntry, *pPrevMapEntry, *pProbeMapEntry;
	BOOLEAN bVaild;

	DBGPRINT(RT_DEBUG_OFF, (" %s. apIdx=%d CliIdx=%d\n", __FUNCTION__,apIdx,CliIdx));

	RTMPRemoveRepeaterAsicEntry(pAd, CliIdx);

	NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock);
	pEntry = &pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx];

	bVaild = TRUE;
	HashIdx = MAC_ADDR_HASH_INDEX(pEntry->CurrentAddress);

	pPrevEntry = NULL;
	pProbeEntry = pAd->ApCfg.ReptCliHash[HashIdx];
	ASSERT(pProbeEntry);

	if (pProbeEntry == NULL)
	{
		bVaild = FALSE;
		goto done;
	}

	if (pProbeEntry != NULL)
	{
		/* update Hash list*/
		do
		{
			if (pProbeEntry == pEntry)
			{
				if (pPrevEntry == NULL)
				{
					pAd->ApCfg.ReptCliHash[HashIdx] = pEntry->pNext;
				}
				else
				{
					pPrevEntry->pNext = pEntry->pNext;
				}
				break;
			}

			pPrevEntry = pProbeEntry;
			pProbeEntry = pProbeEntry->pNext;
		} while (pProbeEntry);
	}
	/* not found !!!*/
	ASSERT(pProbeEntry != NULL);

	if (pProbeEntry == NULL)
	{
		bVaild = FALSE;
		goto done;
	}

	pMapEntry = &pAd->ApCfg.ApCliTab[apIdx].RepeaterCliMap[CliIdx];

	HashIdx = MAC_ADDR_HASH_INDEX(pEntry->OriginalAddress);

	pPrevMapEntry = NULL;
	pProbeMapEntry = pAd->ApCfg.ReptMapHash[HashIdx];
	ASSERT(pProbeMapEntry);
	if (pProbeMapEntry != NULL)
	{
		/* update Hash list*/
		do
		{
			if (pProbeMapEntry == pMapEntry)
			{
				if (pPrevMapEntry == NULL)
				{
					pAd->ApCfg.ReptMapHash[HashIdx] = pMapEntry->pNext;
				}
				else
				{
					pPrevMapEntry->pNext = pMapEntry->pNext;
				}
				break;
			}

			pPrevMapEntry = pProbeMapEntry;
			pProbeMapEntry = pProbeMapEntry->pNext;
		} while (pProbeMapEntry);
	}
	/* not found !!!*/
	ASSERT(pProbeMapEntry != NULL);

done:

	pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].CliConnectState = 0;
	NdisZeroMemory(pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].OriginalAddress, MAC_ADDR_LEN);

	if ((bVaild == TRUE) && (pAd->ApCfg.RepeaterCliSize > 0))
	pAd->ApCfg.RepeaterCliSize--;

	/* set the apcli interface be invalid. */
	pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].CliValid = FALSE;
	pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].CliEnable = FALSE;

	NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);

	return;
}
Exemplo n.º 24
0
VOID
IndicateRxToWrapper(
	MTL	*mtl
	)
{
	UCHAR	*BufferPtr;
	USHORT	BufferLength = 0;
	NDIS_STATUS	Status = NDIS_STATUS_SUCCESS;
	ADAPTER	*Adapter;
	MTL_AS	*as;
	MTL_RX_TBL	*RxTable;

	NdisAcquireSpinLock(&mtl->lock);

	Adapter = mtl->Adapter;
	RxTable = &mtl->rx_tbl;

	while (!IsRxIndicationFifoEmpty(mtl))
	{
		NdisAcquireSpinLock(&RxTable->lock);

		//
		// get the next completed rx assembly
		//
   		as = GetAssemblyFromRxIndicationFifo(mtl);

		if (!as)
		{
			D_LOG(D_ALWAYS, ("IndicateRx: Got a NULL as from queue! mtl: 0x%p", mtl));
			RxTable->IndicateReceiveError1++;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}


		//
		// if this is an old ras frame then we must strip off
		// the mac header Dst[6] + Src[6] + Length[2]
		//
		if (mtl->RecvFramingBits & RAS_FRAMING)
		{
			//
			// pass over the mac header - tommyd does not want to see this
			//
			BufferPtr = as->buf + 14;
	
			//
			// indicate with the size of the ethernet packet not the received size
			// this takes care of the old driver that does padding on small frames
			//
			BufferLength = as->buf[12];
			BufferLength = BufferLength << 8;
			BufferLength += as->buf[13];
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: WrapperFrameType: RAS"));
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: BufPtr: 0x%p, BufLen: %d", BufferPtr, BufferLength));
		}
		else if (mtl->RecvFramingBits & PPP_FRAMING)
		{
			//
			// the received buffer is the data that needs to be inidcated
			//
			BufferPtr = as->buf;
	
			//
			// the received length is the length that needs to be indicated
			//
			BufferLength = as->len;
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: WrapperFrameType: PPP"));
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: BufPtr: 0x%p, BufLen: %d", BufferPtr, BufferLength));
		}
		else
		{
			//
			// unknown framing - what to do what to do
			// throw it away
			//
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: mtl: 0x%p, Unknown WrapperFramming: 0x%x", mtl, mtl->RecvFramingBits));
			RxTable->IndicateReceiveError2++;
			as->tot = 0;
			as->Queued = 0;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}
	
		if (BufferLength > MTL_MAC_MTU)
		{
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: mtl: 0x%p, ReceiveLength > MAX ALLOWED (1514):  RxLength: %d", mtl, as->len));
			RxTable->IndicateReceiveError3++;
			as->tot = 0;
			as->Queued = 0;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}

		//
		// send frame up
		//
		if (mtl->LinkHandle)
		{
			/* release assembly descriptor */
			NdisReleaseSpinLock(&RxTable->lock);

			NdisReleaseSpinLock(&mtl->lock);

			NdisMWanIndicateReceive(&Status,
									Adapter->Handle,
									mtl->LinkHandle,
									BufferPtr,
									BufferLength);

			NdisAcquireSpinLock(&mtl->lock);

			NdisAcquireSpinLock(&RxTable->lock);

			mtl->RecvCompleteScheduled = 1;
		}
	
	
		/* mark as free now */
		as->tot = 0;

		//
		// mark this guy as being free
		//
		as->Queued = 0;

		/* release assembly descriptor */
		NdisReleaseSpinLock(&RxTable->lock);
	}

	//
	// exit code
	// release spinlock and return
	//
    exit_code:

	NdisReleaseSpinLock(&mtl->lock);
}
Exemplo n.º 25
0
VOID RTMPRepeaterInsertInvaildMacEntry(
	IN PRTMP_ADAPTER pAd,
	IN PUCHAR pAddr)
{
	UCHAR HashIdx, idx = 0;
	INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL;
	INVAILD_TRIGGER_MAC_ENTRY *pCurrEntry = NULL;

	if (pAd->ApCfg.ReptControl.ReptInVaildMacSize >= 32)
		return;

	if (MAC_ADDR_EQUAL(pAddr, ZERO_MAC_ADDR))
		return;

	NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock);
	for (idx = 0; idx< 32; idx++)
	{
		pEntry = &pAd->ApCfg.ReptControl.RepeaterInvaildEntry[idx];

		if (MAC_ADDR_EQUAL(pEntry->MacAddr, pAddr))
		{
			if (pEntry->bInsert)
			{
				NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);
				return;
			}
			else
			{
				pEntry->bInsert = TRUE;
				break;
			}
		}

		/* pick up the first available vacancy*/
		if (pEntry->bInsert == FALSE)
		{
			NdisZeroMemory(pEntry->MacAddr, MAC_ADDR_LEN);
			COPY_MAC_ADDR(pEntry->MacAddr, pAddr);
			pEntry->bInsert = TRUE;
			break;
		}
	}

	/* add this entry into HASH table */
	if (pEntry)
	{
		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
		pEntry->pNext = NULL;

		if (pAd->ApCfg.ReptControl.ReptInvaildHash[HashIdx] == NULL)
		{
			pAd->ApCfg.ReptControl.ReptInvaildHash[HashIdx] = pEntry;
		}
		else
		{
			pCurrEntry = pAd->ApCfg.ReptControl.ReptInvaildHash[HashIdx];
			while (pCurrEntry->pNext != NULL)
				pCurrEntry = pCurrEntry->pNext;
			pCurrEntry->pNext = pEntry;
		}
	}

	DBGPRINT(RT_DEBUG_ERROR, (" Store Invaild MacAddr = %02x:%02x:%02x:%02x:%02x:%02x. !!!\n",
				PRINT_MAC(pEntry->MacAddr)));

	pAd->ApCfg.ReptControl.ReptInVaildMacSize++;
	NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock);

	return;
}
Exemplo n.º 26
0
//
// process a wan packet for transmition to idd level
//
// all packets will stay on one queue and the MacReserved fields will be used
// to indicate what state the packet is in
//
// we will use the MacReserved fields provided in the NdisWanPacket as follows:
//
// MacReserved1 - Store a pointer to our local tx descriptor
// MacReserved2 - This will be a boolean flag that will be set when this packet
//                can be completed (NdisMWanSendComplete)
// MacReserved3 - This will be the time to live counter for the wanpacket.
//                If it is not completed we will go ahead and complete it.
//
// MacReserved4
//
VOID
mtl__tx_packet(
	MTL *mtl,
	NDIS_WAN_PACKET *WanPacket
	)
{
	UINT			BytesLeftToTx, FragDataLength, FragNumber, FragSize;
    UINT			TotalPacketLength;
    UCHAR           *FragDataPtr;
    MTL_TX_PKT      *MtlTxPacket;
    MTL_HDR         MtlHeader;
	USHORT			TxFlags;
	ADAPTER			*Adapter = mtl->Adapter;
	PUCHAR			MyStartBuffer;
	CM				*cm = (CM*)mtl->cm;

    D_LOG(D_ENTRY, ("mtl_tx_packet: entry, mtl: 0x%lx, WanPacket: 0x%lx\n", mtl, WanPacket));

	NdisAcquireSpinLock(&mtl->lock);

	IncrementGlobalCount(GlobalSends);

	//
	// queue up the wanpacket
	//
	AddToWanPacketTxFifo(mtl, WanPacket);

	//
	// get a local packet descriptor
	//
	MtlTxPacket = GetLocalTxDescriptor(mtl);

	//
	// make sure this is a valid descriptor
	//
	if (!MtlTxPacket)
	{
		D_LOG(DIGIMTL, ("mtl__tx_proc: Got a NULL Packet off of Local Descriptor Free List\n"));

		//
		// grab wan packet fifo lock
		//
		NdisAcquireSpinLock(&mtl->WanPacketFifo.lock);

		MarkWanPacketForCompletion(WanPacket);

		//
		// release the wan packet fifo lock
		//
		NdisReleaseSpinLock(&mtl->WanPacketFifo.lock);

		goto exit_code;
	}

	//
	// grab wan packet fifo lock
	//
	NdisAcquireSpinLock(&mtl->WanPacketFifo.lock);

	SetTxDescriptorInWanPacket(WanPacket, MtlTxPacket);

	//
	// release the wan packet fifo lock
	//
	NdisReleaseSpinLock(&mtl->WanPacketFifo.lock);

	//
	// grab the descriptor lock
	//
	NdisAcquireSpinLock(&MtlTxPacket->lock);

	IncrementGlobalCount(MtlSends1);

	/* if not connected, give up */
	if ( !mtl->is_conn || cm->PPPToDKF)
	{
		D_LOG(DIGIMTL, ("mtl__tx_proc: packet on non-connected mtl, ignored\n"));
	
		IncrementGlobalCount(MtlSends2);

		goto xmit_error;
	}

	D_LOG(DIGIMTL, ("mtl__tx_proc: LocalPkt: 0x%lx, WanPkt: 0x%lx, WanPktLen: %d\n", MtlTxPacket, WanPacket, WanPacket->CurrentLength));
		
	//
	// get length of wan packet
	//
	TotalPacketLength = WanPacket->CurrentLength;

	//
	// my start buffer is WanPacket->CurrentBuffer - 14
	//
	MyStartBuffer = WanPacket->CurrentBuffer - 14;

	if (mtl->SendFramingBits & RAS_FRAMING)
	{
		D_LOG(DIGIMTL, ("mtl__tx_proc: Transmit WrapperFrameType: RAS\n"));

		// add dest eaddr
		// StartBuffer + 0
		//
		NdisMoveMemory (MyStartBuffer + DST_ADDR_INDEX,
						cm->DstAddr,
						6);
			
		//
		// add source eaddr
		// StartBuffer + 6
		//
		NdisMoveMemory (MyStartBuffer + SRC_ADDR_INDEX,
						cm->SrcAddr,
						6);
			
		//
		// add new length to buffer
		// StartBuffer + 12
		//
		MyStartBuffer[12] = TotalPacketLength >> 8;
		MyStartBuffer[13] = TotalPacketLength & 0xFF;
			
		//
		// data now begins at MyStartBuffer
		//
		MtlTxPacket->frag_buf = MyStartBuffer;

		//
		// new transmit length is a mac header larger
		//
		TotalPacketLength += 14;
	}
Exemplo n.º 27
0
static void lock(void)
{
	NdisAcquireSpinLock(&_lock);
}
Exemplo n.º 28
0
VOID
OvsAcquireCtrlLock()
{
    NdisAcquireSpinLock(gOvsCtrlLock);
}
Exemplo n.º 29
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 void *Context)
{
	struct rt_rtmp_adapter *pAd;
	struct rt_rtmp_os_task *pTask;
	int status;
	status = 0;

	pTask = Context;
	pAd = 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. */
		struct rt_cmdqelmt *pCmdQElmt = NULL;

		NdisAcquireSpinLock(&pAd->CmdQLock);
		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
		while (pAd->CmdQ.size) {
			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
			if (pCmdQElmt) {
				if (pCmdQElmt->CmdFromNdis == TRUE) {
					if (pCmdQElmt->buffer != NULL)
						os_free_mem(pAd,
							    pCmdQElmt->buffer);
					os_free_mem(pAd, (u8 *)pCmdQElmt);
				} else {
					if ((pCmdQElmt->buffer != NULL)
					    && (pCmdQElmt->bufferlength != 0))
						os_free_mem(pAd,
							    pCmdQElmt->buffer);
					os_free_mem(pAd, (u8 *)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;

}
Exemplo n.º 30
0
/*
========================================================================
Routine Description:
    Close kernel threads.

Arguments:
	*pAd				the raxx interface data pointer

Return Value:
    NONE

Note:
========================================================================
*/
VOID RtmpMgmtTaskExit(
	IN RTMP_ADAPTER *pAd)
{
	INT			ret;
	RTMP_OS_TASK	*pTask;
	
	/* Sleep 50 milliseconds so pending io might finish normally */
	RTMPusecDelay(50000);

	/* We want to wait until all pending receives and sends to the */
	/* device object. We cancel any */
	/* irps. Wait until sends and receives have stopped. */
	RTUSBCancelPendingIRPs(pAd);

	/* We need clear timerQ related structure before exits of the timer thread. */
	RtmpTimerQExit(pAd);

	/* Terminate Mlme Thread */
	pTask = &pAd->mlmeTask;
	ret = RtmpOSTaskKill(pTask);
	if (ret == NDIS_STATUS_FAILURE)
	{
/*		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */
/*					RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */
		DBGPRINT(RT_DEBUG_ERROR, ("kill mlme task failed!\n"));
	}

	/* Terminate cmdQ thread */
	pTask = &pAd->cmdQTask;
	RTMP_OS_TASK_LEGALITY(pTask)
	{
		NdisAcquireSpinLock(&pAd->CmdQLock);
		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
		NdisReleaseSpinLock(&pAd->CmdQLock);

		/*RTUSBCMDUp(&pAd->cmdQTask); */
		ret = RtmpOSTaskKill(pTask);
		if (ret == NDIS_STATUS_FAILURE)
		{
/*			DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */
/*					RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */
			DBGPRINT(RT_DEBUG_ERROR, ("kill command task failed!\n"));
		}
		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
	}

	/* Terminate timer thread */
	pTask = &pAd->timerTask;
	ret = RtmpOSTaskKill(pTask);
	if (ret == NDIS_STATUS_FAILURE)
	{
/*		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */
/*					RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */
		DBGPRINT(RT_DEBUG_ERROR, ("kill timer task failed!\n"));
	}

#ifdef WSC_INCLUDED
	WscThreadExit(pAd);
#endif /* WSC_INCLUDED */

}