예제 #1
0
/***************************************************************************
Routine Description:

    This is the defered processing routine for interrupts.  It
    reads from the Interrupt Status Register any outstanding
    interrupts and handles them.

Arguments:

    MiniportAdapterContext - a handle to the adapter block.

Return Value:

    NONE.
*****************************************************************************/
void R6040HandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext)
{
    // The adapter to process
    PR6040_ADAPTER Adapter = ((PR6040_ADAPTER)MiniportAdapterContext);

    NdisDprAcquireSpinLock(&Adapter->Lock);

    // Handle the interrupts
    if (Adapter->InterruptStatus & MISR_TXEND)
    {
        NdisAcquireSpinLock(&Adapter->SendLock);

        // Handle the transmit
        R6040XmitDpc(Adapter);

        NdisReleaseSpinLock(&Adapter->SendLock);
    }

    if (Adapter->InterruptStatus & MISR_RXEND)
    {
        NdisDprAcquireSpinLock(&Adapter->RcvLock);

        // For receives, call this to handle the receive
        R6040RcvDpc(Adapter);

        NdisDprReleaseSpinLock(&Adapter->RcvLock);
    }

    NdisDprReleaseSpinLock(&Adapter->Lock);
}
예제 #2
0
파일: send.c 프로젝트: BillTheBest/WinNT4
STATIC
VOID
LtIndicateReceiveComplete(
    IN PLOOP_ADAPTER    Adapter
    )
{
    PLOOP_OPEN      Open;
    PLIST_ENTRY     CurrentLink = Adapter->OpenBindings.Flink;

    while(CurrentLink != &Adapter->OpenBindings)  {

        Open = CONTAINING_RECORD(
                   CurrentLink,
                   LOOP_OPEN,
                   OpenList);

        if (Open->Flags & BINDING_RECEIVED_PACKET)  {

            NdisIndicateReceiveComplete(Open->NdisBindingContext);

            NdisDprAcquireSpinLock(&Adapter->Lock);
            Open->Flags &= ~BINDING_RECEIVED_PACKET;
            NdisDprReleaseSpinLock(&Adapter->Lock);

            }

        CurrentLink = CurrentLink->Flink;
        }
}
예제 #3
0
파일: flt_dbg.c 프로젝트: TLmaK0/weppinhole
VOID
filterAcquireSpinLock(
	IN	PFILTER_LOCK		pLock,
	IN	ULONG				FileNumber,
	IN	ULONG				LineNumber,
    IN  BOOLEAN             DispatchLevel
)
{

    if (DispatchLevel)
    {
	    NdisDprAcquireSpinLock(&(filterdLockLock));
    }
    else
    {
        NdisAcquireSpinLock(&(filterdLockLock));
    }
	if (pLock->Signature != FILT_LOCK_SIG)
	{
		DbgPrint("Trying to acquire uninited lock 0x%x, File %c%c%c%c, Line %d\n",
				pLock,
				(CHAR)(FileNumber & 0xff),
				(CHAR)((FileNumber >> 8) & 0xff),
				(CHAR)((FileNumber >> 16) & 0xff),
				(CHAR)((FileNumber >> 24) & 0xff),
				LineNumber);
		DbgBreakPoint();
	}
예제 #4
0
파일: send.c 프로젝트: BillTheBest/WinNT4
VOID
LoopTimerProc(
    IN PVOID SystemSpecific1,
    IN PVOID Context,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
    )
{
    PLOOP_ADAPTER Adapter = (PLOOP_ADAPTER)Context;

    DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, (" --> LoopTimerProc\n"));

    NdisDprAcquireSpinLock(&Adapter->Lock);
    Adapter->References++;
    Adapter->TimerSet = FALSE;

    if ((Adapter->Loopback != NULL) && !Adapter->InTimerProc)  {
        Adapter->InTimerProc = TRUE;
        LoopProcessLoopback(Adapter);
        Adapter->InTimerProc = FALSE;
        }

    Adapter->References--;
    NdisDprReleaseSpinLock(&Adapter->Lock);
}
예제 #5
0
VOID
ndisprotAcquireSpinLock(
	IN	PNPROT_LOCK		    pLock,
    IN  BOOLEAN             DispatchLevel,
	IN	ULONG				FileNumber,
	IN	ULONG				LineNumber
)
{
	PKTHREAD		pThread;

	pThread = KeGetCurrentThread();
    if (DispatchLevel == TRUE)
    {
        NdisDprAcquireSpinLock(&(ndisprotdLockLock));
    }
    else
    {
	    NdisAcquireSpinLock(&(ndisprotdLockLock));
    }
	if (pLock->Signature != NPROTL_SIG)
	{
		DbgPrint("Trying to acquire uninited lock 0x%x, File %c%c%c%c, Line %d\n",
				pLock,
				(CHAR)(FileNumber & 0xff),
				(CHAR)((FileNumber >> 8) & 0xff),
				(CHAR)((FileNumber >> 16) & 0xff),
				(CHAR)((FileNumber >> 24) & 0xff),
				LineNumber);
		DbgBreakPoint();
	}
예제 #6
0
VOID tapAdapterAcquireLock(__in PTAP_ADAPTER_CONTEXT Adapter, __in BOOLEAN DispatchLevel) {
  ASSERT(!DispatchLevel || (DISPATCH_LEVEL == KeGetCurrentIrql()));

  if (DispatchLevel) {
    NdisDprAcquireSpinLock(&Adapter->AdapterLock);
  } else {
    NdisAcquireSpinLock(&Adapter->AdapterLock);
  }
}
VOID ParaNdis6_RSSAnalyzeReceivedPacket(
    PARANDIS_RSS_PARAMS *RSSParameters,
    PVOID dataBuffer,
    PNET_PACKET_INFO packetInfo)
{
    NdisDprAcquireSpinLock(&RSSParameters->RSSSettingsLock);
    if(RSSParameters->RSSMode != PARANDIS_RSS_DISABLED)
    {
        RSSCalcHash(RSSParameters, dataBuffer, packetInfo);
    }
    NdisDprReleaseSpinLock(&RSSParameters->RSSSettingsLock);
}
예제 #8
0
// 过滤向外发送的数据,从MPSendPackets或者MPSend函数调用
// 如果从MPSendPackets调用就运行在IRQL <= DISPATCH_LEVEL级别
// 如果从MPSend调用,就运行在IRQL == DISPATCH_LEVEL级别
BOOLEAN FltFilterSendPacket(
				IN PADAPT          pAdapt,
				IN PNDIS_PACKET   pSendPacket,
				IN BOOLEAN         bDispatchLevel  // TRUE -> IRQL == DISPATCH_LEVEL
	)
{
	BOOLEAN bPass = TRUE;
	PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
	UCHAR buffer[MAX_PACKET_HEADER_LEN];
	ULONG nReadBytes;
	
	// 当使用过滤数据时,要获取旋转锁
	if(bDispatchLevel)
	{
		NdisDprAcquireSpinLock(&pAdapt->Lock);
	}
	else
	{
		NdisAcquireSpinLock(&pAdapt->Lock);
	}
	
	// 设置统计数字
	pFilterContext->Statistics.nMPSendPktsCt ++;
	
	// 如果没有设置过滤规则,则放行所有封包
	if(pFilterContext->pFilterList == NULL)
		goto ExitTheFilter;
	
	////////////////////////////////////////////////////
	// 读取封包中的数据,这里仅读取封包头即可
	FltReadPacketData(pSendPacket, buffer, MAX_PACKET_HEADER_LEN, &nReadBytes);
	// 检查过滤规则,看看是否允许这个封包通过
	bPass = FltCheckFilterRules(pFilterContext->pFilterList, buffer, nReadBytes, TRUE);
	
	if(!bPass)
	{
		// 拒绝了一个封包
		pFilterContext->Statistics.nMPSendPktsDropped ++;
	}
	
ExitTheFilter:
	// 过滤之后要释放旋转锁
	if(bDispatchLevel)
		NdisDprReleaseSpinLock(&pAdapt->Lock);
	else
		NdisReleaseSpinLock(&pAdapt->Lock);
	
	return bPass;
}
예제 #9
0
void	_rtw_spinlock_ex(_lock	*plock)
{

#ifdef PLATFORM_LINUX

	spin_lock(plock);

#endif
	
#ifdef PLATFORM_WINDOWS

	NdisDprAcquireSpinLock(plock);

#endif
	
}
예제 #10
0
파일: protocol.c 프로젝트: layerfsd/natflt
VOID
natpQueueReceivedPacket(
    IN PFILTER_ADAPTER pAdapt,
    IN PNDIS_PACKET Packet,
    IN BOOLEAN DoIndicate
    )
{
    PNDIS_PACKET PacketArray[MAX_RCV_PKT_ARR_SZ];
    ULONG NumberOfPackets = 0, i;

    NdisDprAcquireSpinLock(&pAdapt->Lock);
    ASSERT(pAdapt->ReceivedPacketCount < MAX_RCV_PKT_ARR_SZ);

    pAdapt->ReceivedPackets[pAdapt->ReceivedPacketCount] = Packet;
    pAdapt->ReceivedPacketCount++;

    if ((pAdapt->ReceivedPacketCount == MAX_RCV_PKT_ARR_SZ) || DoIndicate){

        NdisMoveMemory(PacketArray,
                       pAdapt->ReceivedPackets,
                       pAdapt->ReceivedPacketCount * sizeof(PNDIS_PACKET));

        NumberOfPackets = pAdapt->ReceivedPacketCount;

	pAdapt->ReceivedPacketCount = 0;
               
        NdisDprReleaseSpinLock(&pAdapt->Lock);

        if ((pAdapt->MiniportHandle != NULL) && (pAdapt->natmDeviceState == NdisDeviceStateD0)){
            NdisMIndicateReceivePacket(pAdapt->MiniportHandle, PacketArray, NumberOfPackets);

        }else{

            if (DoIndicate)
                NumberOfPackets  -= 1;

            for (i = 0; i < NumberOfPackets; i++)
                natmReturnPacket(pAdapt, PacketArray[i]);

        }

    }else
        NdisDprReleaseSpinLock(&pAdapt->Lock);
                  
}
void	_spinlock_ex(_lock	*plock)
{

#ifdef PLATFORM_LINUX

	//eason 20100210 spin_lock(plock);
	cyg_mutex_t * mut_t = plock;	
	cyg_mutex_lock(mut_t);

#endif
	
#ifdef PLATFORM_WINDOWS

	NdisDprAcquireSpinLock(plock);

#endif
	
}
예제 #12
0
파일: send.c 프로젝트: BillTheBest/WinNT4
STATIC
VOID
LtIndicateReceive(
    IN PLOOP_ADAPTER    Adapter,
    IN UINT             PacketType,
    IN PVOID            HeaderBuffer,
    IN UINT             HeaderBufferSize,
    IN PVOID            LookaheadBuffer,
    IN UINT             LookaheadBufferSize,
    IN UINT             PacketSize
    )
{
    PLOOP_OPEN      Open;
    PLIST_ENTRY     CurrentLink = Adapter->OpenBindings.Flink;
    NDIS_STATUS     Status;

    while(CurrentLink != &Adapter->OpenBindings)  {

        Open = CONTAINING_RECORD(
                   CurrentLink,
                   LOOP_OPEN,
                   OpenList);

        if (PacketType & Open->CurrentPacketFilter)  {

            NdisIndicateReceive(
                &Status,
                Open->NdisBindingContext,
                NULL,
                HeaderBuffer,
                HeaderBufferSize,
                LookaheadBuffer,
                LookaheadBufferSize,
                PacketSize);

            NdisDprAcquireSpinLock(&Adapter->Lock);
            Open->Flags |= BINDING_RECEIVED_PACKET;
            NdisDprReleaseSpinLock(&Adapter->Lock);

            }

        CurrentLink = CurrentLink->Flink;
        }
}
예제 #13
0
파일: protocol.c 프로젝트: layerfsd/natflt
VOID
	natpFlushReceiveQueue(
		IN PFILTER_ADAPTER pAdapt
    )
{
    PNDIS_PACKET PacketArray[MAX_RCV_PKT_ARR_SZ];
    ULONG NumberOfPackets = 0, i;

    __try{

        NdisDprAcquireSpinLock(&pAdapt->Lock);

        if (pAdapt->ReceivedPacketCount > 0){

            NdisMoveMemory(PacketArray,
                            pAdapt->ReceivedPackets,
                            pAdapt->ReceivedPacketCount * sizeof(PNDIS_PACKET));

            NumberOfPackets = pAdapt->ReceivedPacketCount;

            pAdapt->ReceivedPacketCount = 0;

            NdisDprReleaseSpinLock(&pAdapt->Lock);
               
            if ((pAdapt->MiniportHandle) && (pAdapt->natmDeviceState == NdisDeviceStateD0)){
                
				NdisMIndicateReceivePacket(pAdapt->MiniportHandle, 
                                           PacketArray, 
                                           NumberOfPackets);
                __leave;
            }

            for (i = 0; i < NumberOfPackets; i ++)
                natmReturnPacket(pAdapt, PacketArray[i]);

            __leave;
        }
        
        NdisDprReleaseSpinLock(&pAdapt->Lock);
    
    }__finally{}

}
CCHAR ParaNdis6_RSSGetCurrentCpuReceiveQueue(PARANDIS_RSS_PARAMS *RSSParameters)
{
    CCHAR res;

    NdisDprAcquireSpinLock(&RSSParameters->RSSSettingsLock);

    if(RSSParameters->RSSMode != PARANDIS_RSS_FULL)
    {
        res = PARANDIS_RECEIVE_QUEUE_UNCLASSIFIED;
    }
    else
    {
        res = FindReceiveQueueForCurrentCpu(&RSSParameters->ActiveRSSScalingSettings);
    }

    NdisDprReleaseSpinLock(&RSSParameters->RSSSettingsLock);

    return res;
}
예제 #15
0
// 过滤接收到的数据,从PtReceivePacket函数调用,运行在DISPATCH_LEVEL IRQL级别
BOOLEAN FltFilterReceivePacket(
				IN PADAPT         pAdapt,
				IN	PNDIS_PACKET   pReceivedPacket
				)
{
	BOOLEAN bPass = TRUE;
	PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
	UCHAR buffer[MAX_PACKET_HEADER_LEN];
	ULONG nReadBytes;
	
	// 当使用过滤数据时,要获取旋转锁
	NdisDprAcquireSpinLock(&pAdapt->Lock);
	
	
	// 设置统计数字
	pFilterContext->Statistics.nPTRcvPktCt ++;

	// 如果没有设置过滤规则,则放行所有封包
	if(pFilterContext->pFilterList == NULL)
		goto ExitTheFilter;
	
	////////////////////////////////////////////////////
	// 读取封包中的数据,这里仅读取封包头即可
	FltReadPacketData(pReceivedPacket, buffer, MAX_PACKET_HEADER_LEN, &nReadBytes);
	if(nReadBytes != MAX_PACKET_HEADER_LEN)
	{
		DBGPRINT(("  FltFilterReceivePacket:  nReadBytes != MAX_PACKET_HEADER_LEN"));
	}
	// 检查过滤规则,看看是否允许这个封包通过
	bPass = FltCheckFilterRules(pFilterContext->pFilterList,buffer, nReadBytes, TRUE);
	if(!bPass)
	{
		// 拒绝了一个封包
		pFilterContext->Statistics.nPTRcvPktDropped ++;
	}

ExitTheFilter:
	// 过滤之后要释放旋转锁
	NdisDprReleaseSpinLock(&pAdapt->Lock);
	
	return bPass;
}
예제 #16
0
// 过滤接收到的数据,从PtReceivePacket函数调用,运行在DISPATCH_LEVEL IRQL级别
BOOLEAN FltFilterReceive(
					IN PADAPT         pAdapt,
					IN NDIS_HANDLE    MacReceiveContext,
					IN PVOID          HeaderBuffer,
					IN UINT           HeaderBufferSize,
					IN PVOID          LookAheadBuffer,
					IN UINT           LookAheadBufferSize,
					IN UINT           PacketSize
					)
{
	BOOLEAN bPass = TRUE;
	PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
	PETHeader pEtherHdr = (PETHeader)HeaderBuffer;
	
	// 当使用过滤数据时,要获取旋转锁
	NdisDprAcquireSpinLock(&pAdapt->Lock);
	
	
	// 设置统计数字
	pFilterContext->Statistics.nPTRcvCt ++;
	// 如果没有设置过滤规则,则放行所有封包
	if(pFilterContext->pFilterList == NULL)
		goto ExitTheFilter;
	
	// 如果不是IP协议,则放行
	if(pEtherHdr->type != 0x8)  
		goto ExitTheFilter;
	
	// 检查过滤规则,看看是否允许这个封包通过
	bPass = FltCheckFilterRules(pFilterContext->pFilterList,LookAheadBuffer, LookAheadBufferSize, FALSE);
	if(!bPass)
	{
		// 拒绝了一个封包
		pFilterContext->Statistics.nPTRcvDropped ++;
	}
	
ExitTheFilter:
	// 过滤之后要释放旋转锁
    NdisDprReleaseSpinLock(&pAdapt->Lock);

	return bPass;
}
CCHAR ParaNdis6_RSSGetScalingDataForPacket(
    PARANDIS_RSS_PARAMS *RSSParameters,
    PNET_PACKET_INFO packetInfo,
    PPROCESSOR_NUMBER targetProcessor)
{
    CCHAR targetQueue;

    NdisDprAcquireSpinLock(&RSSParameters->RSSSettingsLock);

    if((RSSParameters->RSSMode != PARANDIS_RSS_FULL) || (packetInfo->RSSHash.Type == 0))
    {
        targetQueue = PARANDIS_RECEIVE_QUEUE_UNCLASSIFIED;
    }
    else
    {
        ULONG indirectionIndex = packetInfo->RSSHash.Value & RSSParameters->ActiveRSSScalingSettings.RSSHashMask;
        *targetProcessor = RSSParameters->ActiveRSSScalingSettings.IndirectionTable[indirectionIndex];
        targetQueue = RSSParameters->ActiveRSSScalingSettings.QueueIndirectionTable[indirectionIndex];
    }

    NdisDprReleaseSpinLock(&RSSParameters->RSSSettingsLock);

    return targetQueue;
}
예제 #18
0
int divert_filter(
   IN PADAPT         pAdapt,
   IN NDIS_HANDLE    MacReceiveContext,
   IN PVOID          HeaderBuffer,
   IN UINT           HeaderBufferSize,
   IN PVOID          LookAheadBuffer,
   IN UINT           LookAheadBufferSize,
   IN UINT           PacketSize
   )
{
#define MAC_SIZE 14
	USHORT               EtherType;
	ULONG                NumberOfBytesRead;
	struct ether_header  *pEthHdr;      // See ../B2Winet/ethernet.h
	struct ip            *pIPHeader;
	struct tcphdr	     *tcp;
	int rc = 0;
	struct divert_packet *dp, *cur;
	NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;

	NdisDprAcquireSpinLock(&pAdapt->Lock);

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

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

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

	pIPHeader = (struct ip * )LookAheadBuffer;

	if (LookAheadBufferSize < 40)
		goto Out;

	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 Outl;

	dp = get_packet();
	if (!dp) {
		DbgPrint("Out of queue - shit\n");
		goto Outl;
	}

	if (LookAheadBufferSize != PacketSize) {
		NDIS_STATUS status;
		PNDIS_PACKET pkt;
		PNDIS_BUFFER buf;
		int len;

		if ((PacketSize + MAC_SIZE) > sizeof(dp->dp_packet)) {
			DbgPrint("cAZZOOOOOOOOOOOOOOOOOOOOOOOOOOo\n");
			goto Fanculo;
		}

		NdisAllocatePacket(&status, &pkt, _packet_pool);
		NdisAllocateBuffer(&status, &buf, _buf_pool,
				   dp->dp_packet + MAC_SIZE,
				   sizeof(dp->dp_packet) - MAC_SIZE);
		NdisChainBufferAtFront(pkt, buf);
		NdisTransferData(&status, pAdapt->BindingHandle,
				 MacReceiveContext, 0,
				 PacketSize, pkt, &len);
		NdisFreeBuffer(buf);
		NdisFreePacket(pkt);
	} else {
		NdisCopyLookaheadData(dp->dp_packet + MAC_SIZE,
				      LookAheadBuffer,
				      LookAheadBufferSize,
				      0);
	}

Fanculo:
	rc = 1;

	memcpy(dp->dp_packet, pEthHdr, MAC_SIZE);

	dp->dp_len   = PacketSize + MAC_SIZE;
	dp->dp_flags = 1;

	kick_pending();

Outl:
	unlock();
Out:
	NdisDprReleaseSpinLock(&pAdapt->Lock);

	return rc;
#undef MAC_SIZE
}
예제 #19
0
파일: st_assoc.c 프로젝트: kcrazy/winekit
VOID 
StaReceiveDisassociation(
                        __in  PSTATION                        pStation,
                        __in  PNIC_RX_FRAGMENT                pNicFragment,
                        __in  ULONG                           TotalLength
                        )
{
    NDIS_STATUS         ndisStatus = NDIS_STATUS_SUCCESS;
    PUCHAR              pPacketBuffer;
    PDOT11_DISASSOC_FRAME   pDot11DisassocFrame = NULL;
    PDOT11_MGMT_HEADER  pMgmtHeader;
    PSTA_BSS_ENTRY      pAPEntry;
    BOOLEAN             bDisassociate = TRUE;

    if (TotalLength < (sizeof(DOT11_MGMT_HEADER) + sizeof(DOT11_DISASSOC_FRAME))) {
        MpTrace(COMP_ASSOC, DBG_LOUD, ("Disassociation packet too short\n"));
        return ;
    }

    pPacketBuffer = Hw11GetFragmentDataStart(pNicFragment);

    //
    // Ref to make sure reset/halt does not leave while we are still working
    //
    STA_INCREMENT_REF(pStation->ConnectContext.AsyncFuncCount);

    //
    // Proceed only if we have received association packet
    //
    NdisDprAcquireSpinLock(&(pStation->ConnectContext.Lock));
    if ((pStation->ConnectContext.ConnectState >= CONN_STATE_READY_TO_CONNECT) &&
        (pStation->ConnectContext.AssociateState > ASSOC_STATE_WAITING_FOR_ASSOCIATE)) {
        pAPEntry = pStation->ConnectContext.ActiveAP;
        pMgmtHeader = (PDOT11_MGMT_HEADER)pPacketBuffer;

        //
        // Check that is a packet from the AP we are interested in
        //
        if (!MP_COMPARE_MAC_ADDRESS(pMgmtHeader->SA, pAPEntry->MacAddress) ||
            !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->BSSID, pAPEntry->Dot11BSSID) ||
            !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->DA, Hw11GetMACAddress(pStation->pNic))) {
            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
            MpTrace(COMP_ASSOC, DBG_LOUD, ("Disassociate packet not for me\n"));
            ndisStatus = NDIS_STATUS_NOT_ACCEPTED;
        }
        else {
            pDot11DisassocFrame = (PDOT11_DISASSOC_FRAME)(pPacketBuffer + sizeof(DOT11_MGMT_HEADER));

            MpTrace(COMP_ASSOC, DBG_NORMAL, ("Received disassociation, reason %d - ", pDot11DisassocFrame->usReasonCode));

            //
            // On a Disassociated, we would just send the deauthenticate
            // packet to the access point & move ourselves to ready state
            //
            if (pStation->ConnectContext.AssociateState == ASSOC_STATE_ASSOCIATED) {
                MpTrace(COMP_ASSOC, DBG_LOUD, ("After we were associated\n"));        

                //
                // We were associated, cleanup state and indicate disassociation
                //
                pStation->ConnectContext.ActiveAP = NULL;
                bDisassociate = TRUE;
                pAPEntry->AssocState = dot11_assoc_state_unauth_unassoc;    // Moving to unauthenticated
                pStation->ConnectContext.AssociateState = ASSOC_STATE_NOT_ASSOCIATED;                
            }
            else {
                MpTrace(COMP_ASSOC, DBG_LOUD, ("While we were associating\n"));        

                //
                // Receive disassociate while still attempting to associate. Set associate failed
                // so appropriate routine knows to fail the association attempt
                //
                pStation->ConnectContext.AssociateState = ASSOC_STATE_REMOTELY_DISASSOCIATED;
                bDisassociate = FALSE;
            }

            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));

            if (bDisassociate) {
                //
                // Send deauthenticate (ignoring status)
                //
                StaSendDeauthentication(
                                       pStation, 
                                       pAPEntry, 
                                       DOT11_MGMT_REASON_UPSPEC_REASON
                                       );

                // Indicate disassociation
                StaIndicateDisassociation(
                                         pStation, 
                                         pAPEntry, 
                                         DOT11_ASSOC_STATUS_PEER_DISASSOCIATED_START | pDot11DisassocFrame->usReasonCode
                                         );

                NdisDprAcquireSpinLock(&(pStation->ConnectContext.Lock));
                if (pStation->ConnectContext.ConnectState >= CONN_STATE_READY_TO_CONNECT) {
                    //
                    // We got disassociated, but we can still connect. We will
                    // queue the periodic scan routine to attempt association
                    //                    
                    StaForceInternalScan(pStation, TRUE);
                }
                NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
            }

            //
            // Raise cost and remove connection ref from the AP entry and raise cost
            //
            pAPEntry->AssocCost += STA_ASSOC_COST_REMOTE_DISCONNECT;
            STA_DECREMENT_REF(pAPEntry->RefCount);
        }
    }
    else {
        NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
    }

    // Done
    STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);    
}
예제 #20
0
파일: st_assoc.c 프로젝트: kcrazy/winekit
NDIS_STATUS
StaAssociate(
            __in  PSTATION        pStation,
            __in  PSTA_BSS_ENTRY  pAPEntry,
            __in  ULONG           AssociateTimeout
            )
{
    NDIS_STATUS         ndisStatus = NDIS_STATUS_SUCCESS;
    PUCHAR              pAssocPacket = NULL;
    USHORT              AssocPacketLength;
    ULONG               StatusCode = 0;

    MpEntry;

    do {
        //
        // Create the associate packet
        //
        ndisStatus = StaCreateAssociateRequestPacket(
                                                    pStation,
                                                    pAPEntry,
                                                    &pAssocPacket,
                                                    &AssocPacketLength
                                                    );
        if (ndisStatus != NDIS_STATUS_SUCCESS) {
            //
            // Complete the association process
            //
            StatusCode = ndisStatus;
            NdisAcquireSpinLock(&(pStation->ConnectContext.Lock));
            if (pStation->ConnectContext.AssociateState == ASSOC_STATE_RECEIVED_AUTHENTICATE) {
                //
                // Reset ourselves to ready to original state
                //
                pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION;
            }
            NdisReleaseSpinLock(&(pStation->ConnectContext.Lock));

            break;
        }

        NdisAcquireSpinLock(&(pStation->ConnectContext.Lock));
        if ((pStation->ConnectContext.ConnectState >= CONN_STATE_READY_TO_CONNECT) &&
            (pStation->ConnectContext.AssociateState == ASSOC_STATE_RECEIVED_AUTHENTICATE)) {
            //
            // Packet will be sent means we will be waiting for packet response
            //
            pStation->ConnectContext.AssociateState = ASSOC_STATE_WAITING_FOR_ASSOCIATE;

            //
            // Save association request packet inside the AP entry. This will be freed
            // on association completion indication
            //
            NdisDprAcquireSpinLock(&(pAPEntry->Lock));
            pAPEntry->pAssocRequest = pAssocPacket;
            pAPEntry->AssocRequestLength = AssocPacketLength;
            NdisDprReleaseSpinLock(&(pAPEntry->Lock));

            NdisReleaseSpinLock(&(pStation->ConnectContext.Lock));
        }
        else {
            //
            // Reset, disconnect, deauthenticated by AP after authentication succeeded
            //
            NdisReleaseSpinLock(&(pStation->ConnectContext.Lock));
            MpTrace(COMP_ASSOC, DBG_LOUD, ("Reset/Disconnect/Deauth while starting association\n"));

            //
            // Assoc packet pointer isnt saved, free it
            //
            StaFreeAssociateRequestPacket(
                pStation, 
                pAPEntry, 
                pAssocPacket, 
                AssocPacketLength
                );

            //
            // Abort association 
            //
            StatusCode = (ULONG)STATUS_CANCELLED;
            break;
        }

        //
        // Send the association request packet
        //
        ndisStatus = Hw11SendMgmtPacket(
                                       pStation->pNic,
                                       pAPEntry,
                                       pAssocPacket,
                                       AssocPacketLength
                                       );
        if (ndisStatus != NDIS_STATUS_SUCCESS) {
            MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Unable to send Association Request packet\n"));
            StatusCode = ndisStatus;

            NdisAcquireSpinLock(&(pStation->ConnectContext.Lock));
            if (pStation->ConnectContext.AssociateState == ASSOC_STATE_WAITING_FOR_AUTHENTICATE) {
                //
                // Reset ourselves to ready to original state
                //
                pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION;
            }

            NdisReleaseSpinLock(&(pStation->ConnectContext.Lock));

            break;
        }
        else {
            // Add an extra refcount for the association timer
            STA_INCREMENT_REF(pStation->ConnectContext.AsyncFuncCount);

            //
            // Set the timeout timer for associate failure case. 
            //
            //NdisMSetTimer(&(pStation->ConnectContext.Timer_AssociateTimeout), AssociateTimeout);
            WdfTimerStart(pStation->ConnectContext.Timer_AssociateTimeout, WDF_REL_TIMEOUT_IN_MS(AssociateTimeout));

        }

        //
        // We dont let the hardware pend the request since we will be 
        // freeing the packet
        //
        MPVERIFY(ndisStatus != NDIS_STATUS_PENDING);
    }while (FALSE);

    //
    // Fail the association if we failed inline, etc
    //
    if (StatusCode != 0) {
        StaAssociateComplete(pStation, DOT11_ASSOC_STATUS_SYSTEM_ERROR);
    }

    return ndisStatus;
}
예제 #21
0
/***************************************************************************
Routine Description:

    This is the real interrupt handler for receive/overflow interrupt.

    Called when a receive interrupt is received. It first indicates
    all packets on the card and finally indicates ReceiveComplete().

Arguments:

    Adapter - Pointer to the adapter block.

Return Value:

    TRUE if done with all receives, else FALSE.
*****************************************************************************/
BOOLEAN R6040RcvDpc(IN PR6040_ADAPTER Adapter)
{
    // Status of a received packet.
    INDICATE_STATUS IndicateStatus = INDICATE_OK;

    // Guess at where the packet is located
    PUCHAR PacketLoc;

    // Flag to tell when the receive process is complete
    BOOLEAN Done = TRUE;

    PUCHAR rxd;
    USHORT rxstatus;
    int total_len;

    do
    {
        // Code to fix a loop we got into where the card had been removed,
        // Now, the NDIS unbind routine calls our shutdown
        // handler which sets a flag
        if (Adapter->ShuttingDown)
        {
            RETAILMSG(R6040DBG, (TEXT("R6040RcvDpc(): Shutdown detected\r\n")));
            break;
        }

        // Default to not indicating NdisMEthIndicateReceiveComplete
        Adapter->IndicateReceiveDone = FALSE;

        // A packet was found on the card, indicate it.
        Adapter->ReceivePacketCount++;

        rxd = Adapter->Rx_ring[Adapter->Rx_desc_add].VirtualAddr;

        READMEM16(rxd + DS_STATUS, rxstatus);
        READMEM16(rxd + DS_LEN, total_len);
        total_len -= 4;  /* Skip CRC 4 byte */

        /* OWN bit=1, no packet coming */
        if (rxstatus & 0x8000)
        {
            IndicateStatus = SKIPPED;
            //RETAILMSG(R6040DBG, (TEXT("R6040RcvDpc(): no packet coming \r\n")));
            break;
        }

        //RETAILMSG(R6040DBG, (TEXT("R6040RcvDpc(): total_len = %d\r\n"), total_len));

        Adapter->Rx_desc_add++;
        // Adapter->Rx_free_cnt++;

        // Copy the data to the network stack
        PacketLoc = rxd + BUF_START;
        Adapter->PacketHeaderLoc =  PacketLoc;

        // Indicate the packet to the wrapper
        IndicateStatus = R6040IndicatePacket(Adapter , total_len);
        if (IndicateStatus != CARD_BAD)
        {
            Adapter->FramesRcvGood++;
        }

        // Handle when the card is unable to indicate good packets
        if (IndicateStatus == CARD_BAD)
        {
            RETAILMSG(R6040DBG,
                (TEXT("R6040RcvDpc(): CARD_BAD: R: <%x %x %x %x> \r\n"),
                Adapter->PacketHeader[0],
                Adapter->PacketHeader[1],
                Adapter->PacketHeader[2],
                Adapter->PacketHeader[3]));

            // Start off with receive interrupts disabled.
            Adapter->NicInterruptMask = MIER_RXENDE | MIER_TXENDE;

            // Reset the adapter
            CardReset(Adapter);
            // Since the adapter was just reset, stop indicating packets.
            break;
        }

        /* Rx data already copy to the upper buffer, now can reuse RX descriptor */
        WRITEMEM16(rxd + DS_STATUS, 0x8000); /* Reuse RX descriptor */

        /* Signal RX ready */
        // NdisRawWritePortUshort( Adapter->IoPAddr + NIC_CONTROL0,Adapter->MacControl);

        /* Move to next RX descriptor */
        if (Adapter->Rx_desc_add >= MAX_RX_DESCRIPTORS)
        {
            Adapter->Rx_desc_add = 0;
            Done = FALSE;
            Adapter->ReceivePacketCount = 0;
            // break;
        }

        // Finally, indicate ReceiveComplete to all protocols which received packets
        if (Adapter->IndicateReceiveDone)
        {
            NdisDprReleaseSpinLock(&Adapter->RcvLock);
            NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
            NdisDprAcquireSpinLock(&Adapter->RcvLock);
            Adapter->IndicateReceiveDone = FALSE;
        }
    }while (TRUE);

    return (Done);
}
예제 #22
0
VOID
NTAPI
MiniportHandleInterrupt (
    IN NDIS_HANDLE MiniportAdapterContext
    )
{
    PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext;
    ULONG txStatus;
    UCHAR command;
    PPACKET_HEADER nicHeader;
    PETH_HEADER ethHeader;
        
    NdisDprAcquireSpinLock(&adapter->Lock);
    
    NDIS_DbgPrint(MAX_TRACE, ("Interrupts pending: 0x%x\n", adapter->InterruptPending));
    
    //
    // Handle a link change
    //
    if (adapter->LinkChange)
    {
        NdisDprReleaseSpinLock(&adapter->Lock);
        NdisMIndicateStatus(adapter->MiniportAdapterHandle,
                            adapter->MediaState == NdisMediaStateConnected ?
                                NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT,
                            NULL,
                            0);
        NdisMIndicateStatusComplete(adapter->MiniportAdapterHandle);
        NdisDprAcquireSpinLock(&adapter->Lock);
        adapter->LinkChange = FALSE;
    }                            
    
    //
    // Handle a TX interrupt
    //
    if (adapter->InterruptPending & (R_I_TXOK | R_I_TXERR))
    {
        while (adapter->TxFull || adapter->DirtyTxDesc != adapter->CurrentTxDesc)
        {
            NdisRawReadPortUlong(adapter->IoBase + R_TXSTS0 +
                                 (adapter->DirtyTxDesc * sizeof(ULONG)), &txStatus);
            
            if (!(txStatus & (R_TXS_STATOK | R_TXS_UNDERRUN | R_TXS_ABORTED)))
            {
                //
                // Not sent yet
                //
                break;
            }
            
            NDIS_DbgPrint(MAX_TRACE, ("Transmission for desc %d complete: 0x%x\n",
                                      adapter->DirtyTxDesc, txStatus));
            
            if (txStatus & R_TXS_STATOK)
            {
                adapter->TransmitOk++;
            }
            else
            {
                adapter->TransmitError++;
            }

            adapter->DirtyTxDesc++;
            adapter->DirtyTxDesc %= TX_DESC_COUNT;
            adapter->InterruptPending &= ~(R_I_TXOK | R_I_TXERR);
            adapter->TxFull = FALSE;
        }
    }
    
    //
    // Handle a good RX interrupt
    //
    if (adapter->InterruptPending & (R_I_RXOK | R_I_RXERR))
    {
        for (;;)
        {
            NdisRawReadPortUchar(adapter->IoBase + R_CMD, &command);
            if (command & R_CMD_RXEMPTY)
            {
                //
                // The buffer is empty
                //
                adapter->InterruptPending &= ~(R_I_RXOK | R_I_RXERR);
                break;
            }
            
            adapter->ReceiveOffset %= RECEIVE_BUFFER_SIZE;
            
            NDIS_DbgPrint(MAX_TRACE, ("Looking for a packet at offset 0x%x\n",
                            adapter->ReceiveOffset));
            nicHeader = (PPACKET_HEADER)(adapter->ReceiveBuffer + adapter->ReceiveOffset);
            if (!(nicHeader->Status & RSR_ROK))
            {
                //
                // Receive failed
                //
                NDIS_DbgPrint(MIN_TRACE, ("Receive failed: 0x%x\n", nicHeader->Status));
                
                if (nicHeader->Status & RSR_FAE)
                {
                    adapter->ReceiveAlignmentError++;
                }
                else if (nicHeader->Status & RSR_CRC)
                {
                    adapter->ReceiveCrcError++;
                }
                adapter->ReceiveError++;
                
                goto NextPacket;
            }
            
            NDIS_DbgPrint(MAX_TRACE, ("Indicating %d byte packet to NDIS\n",
                           nicHeader->PacketLength - RECV_CRC_LENGTH));
   
            ethHeader = (PETH_HEADER)(nicHeader + 1);
            NdisMEthIndicateReceive(adapter->MiniportAdapterHandle,
                                    NULL,
                                    (PVOID)(ethHeader),
                                    sizeof(ETH_HEADER),
                                    (PVOID)(ethHeader + 1),
                                    nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH,
                                    nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH);
            adapter->ReceiveOk++;
            
        NextPacket:
            adapter->ReceiveOffset += nicHeader->PacketLength + sizeof(PACKET_HEADER);
            adapter->ReceiveOffset = (adapter->ReceiveOffset + 3) & ~3;
            NdisRawWritePortUshort(adapter->IoBase + R_CAPR, adapter->ReceiveOffset - 0x10);
            
            if (adapter->InterruptPending & (R_I_RXOVRFLW | R_I_FIFOOVR))
            {
                //
                // We can only clear these interrupts once CAPR has been reset
                //
                NdisRawWritePortUshort(adapter->IoBase + R_IS, R_I_RXOVRFLW | R_I_FIFOOVR);
                adapter->InterruptPending &= ~(R_I_RXOVRFLW | R_I_FIFOOVR);
            }
        }
        
        NdisMEthIndicateReceiveComplete(adapter->MiniportAdapterHandle);
    }
    
    NdisDprReleaseSpinLock(&adapter->Lock);
}
예제 #23
0
INDICATE_STATUS
R6040IndicatePacket(
    IN PR6040_ADAPTER Adapter,
    IN INT  Len
    )

/*++

Routine Description:

    Indicates the first packet on the card to the protocols.

    NOTE: For MP, non-x86 architectures, this assumes that the packet has been
    read from the card and into Adapter->PacketHeader and Adapter->Lookahead.

    NOTE: For UP x86 systems this assumes that the packet header has been
    read into Adapter->PacketHeader and the minimal lookahead stored in
    Adapter->Lookahead

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    CARD_BAD if the card should be reset;
    INDICATE_OK otherwise.

--*/

{
    // Length of the packet
    UINT PacketLen = Len;

    // Length of the lookahead buffer
    UINT IndicateLen;

    if (PacketLen > 1514) {
        RETAILMSG(R6040DBG,
            (TEXT("R6040:IndicatePacket Third CARD_BAD check failed\r\n")));
        return(SKIPPED);
    }

    // Lookahead amount to indicate
    IndicateLen = (PacketLen > (Adapter->MaxLookAhead + R6040_HEADER_SIZE )) ?
                           (Adapter->MaxLookAhead + R6040_HEADER_SIZE ) :
                           PacketLen;

    // Indicate packet
    Adapter->PacketLen = PacketLen;
    if (IndicateLen < R6040_HEADER_SIZE)
    {
        // Runt Packet
        NdisDprReleaseSpinLock(&Adapter->RcvLock);
        NdisMEthIndicateReceive(
                Adapter->MiniportAdapterHandle,
                (NDIS_HANDLE)Adapter,
                (PCHAR)(Adapter->PacketHeaderLoc),
                IndicateLen,
                NULL,
                0,
                0
                );
        NdisDprAcquireSpinLock(&Adapter->RcvLock);

    } else {
        NdisDprReleaseSpinLock(&Adapter->RcvLock);
        NdisMEthIndicateReceive(
                Adapter->MiniportAdapterHandle,
                (NDIS_HANDLE)Adapter,
                (PCHAR)(Adapter->PacketHeaderLoc),
                R6040_HEADER_SIZE,
                (PCHAR)(Adapter->PacketHeaderLoc) + R6040_HEADER_SIZE,
                IndicateLen - R6040_HEADER_SIZE,
                PacketLen - R6040_HEADER_SIZE
                );
        NdisDprAcquireSpinLock(&Adapter->RcvLock);
    }

    Adapter->IndicateReceiveDone = TRUE;
    return INDICATE_OK;
}
예제 #24
0
파일: send.c 프로젝트: BillTheBest/WinNT4
STATIC
VOID
LoopProcessLoopback(
    PLOOP_ADAPTER Adapter
    )
{
    PNDIS_PACKET LoopPacket;
    PLOOP_PACKET_RESERVED Reserved;
    PLOOP_OPEN Open;
    UINT BufferLength;
    UINT IndicateLen;
    UINT AddressType;
    UCHAR DestAddress[FDDI_LENGTH_OF_LONG_ADDRESS];

    DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, (" --> LoopProcessLoopback\n"));

    while ((Adapter->Loopback != NULL) && !Adapter->ResetInProgress)  {

        // dequeue the packet at the head of the loopback queue

        LoopPacket = Adapter->Loopback;
        Adapter->CurrentLoopback = LoopPacket;
        Reserved = PLOOP_RESERVED_FROM_PACKET(LoopPacket);
        Adapter->Loopback = Reserved->Next;
        if (Adapter->Loopback == NULL)
            Adapter->LastLoopback = NULL;

        DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("Dequeued packet %lx\n",LoopPacket));

        IndicateLen = (Reserved->PacketLength > Adapter->MaxLookAhead) ?
                       Adapter->MaxLookAhead : Reserved->PacketLength;

        Adapter->GeneralMandatory[GM_RECEIVE_GOOD]++;
        NdisDprReleaseSpinLock(&Adapter->Lock);

        LoopCopyFromPacketToBuffer(
            LoopPacket,
            0,
            IndicateLen,
            Adapter->LoopBuffer,
            &BufferLength
            );

        // indicate the packet as appropriate

        switch (Adapter->Medium)  {
            case NdisMedium802_3:
            case NdisMediumDix:
                EthFilterIndicateReceive(
                    Adapter->Filter.Eth,
                    (NDIS_HANDLE)NULL,
                    (PCHAR)Adapter->LoopBuffer,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMedium802_5:
                TrFilterIndicateReceive(
                    Adapter->Filter.Tr,
                    (NDIS_HANDLE)NULL,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMediumFddi:

                // just copy over the long address size, even though it may
                // be a short address

                NdisMoveMemory(
                    DestAddress,
                    Adapter->LoopBuffer+1,
                    FDDI_LENGTH_OF_LONG_ADDRESS
                    );

                FddiFilterIndicateReceive(
                    Adapter->Filter.Fddi,
                    (NDIS_HANDLE)NULL,
                    (PCHAR)DestAddress,
                    ((*(Adapter->LoopBuffer) & 0x40) ? FDDI_LENGTH_OF_LONG_ADDRESS :
                                                       FDDI_LENGTH_OF_SHORT_ADDRESS),
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMediumLocalTalk:
                if (LOOP_LT_IS_BROADCAST(Adapter->LoopBuffer[0]))
                    AddressType = NDIS_PACKET_TYPE_BROADCAST;
                else
                    AddressType = NDIS_PACKET_TYPE_DIRECTED;

                LtIndicateReceive(
                    Adapter,
                    AddressType,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            case NdisMediumArcnet878_2:
                if (LOOP_ARC_IS_BROADCAST(Adapter->LoopBuffer[1]))
                    AddressType = NDIS_PACKET_TYPE_BROADCAST;
                else
                    AddressType = NDIS_PACKET_TYPE_DIRECTED;

                LtIndicateReceive(
                    Adapter,
                    AddressType,
                    Adapter->LoopBuffer,
                    Reserved->HeaderLength,
                    (Adapter->LoopBuffer)+(Reserved->HeaderLength),
                    IndicateLen-(Reserved->HeaderLength),
                    (Reserved->PacketLength)-(Reserved->HeaderLength)
                    );
                break;
            default:
                ASSERT(FALSE);    // should never get here
                break;
            }

        // complete the send

        Open = PLOOP_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO,
            ("Completing Send for binding %lx\n",Open));
        NdisCompleteSend(
            Open->NdisBindingContext,
            LoopPacket,
            NDIS_STATUS_SUCCESS
            );
        NdisDprAcquireSpinLock(&Adapter->Lock);
        Adapter->GeneralMandatory[GM_TRANSMIT_GOOD]++;
        // remove reference for send just completed
        Open->References--;
        }

    // rearm timer if there are still packets to loop back and the timer is
    //  not already ticking away

    if (Adapter->Loopback != NULL && !Adapter->TimerSet)  {
        DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("More packets to loopback\n"));
        Adapter->TimerSet = TRUE;
        NdisDprReleaseSpinLock(&Adapter->Lock);
        NdisSetTimer(
            &Adapter->LoopTimer,
            25
            );
        NdisDprAcquireSpinLock(&Adapter->Lock);
        }

    // issue indicate receive completes as necessary

    switch (Adapter->Medium)  {
        case NdisMedium802_3:
        case NdisMediumDix:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            EthFilterIndicateReceiveComplete(Adapter->Filter.Eth);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMedium802_5:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            TrFilterIndicateReceiveComplete(Adapter->Filter.Tr);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMediumFddi:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            FddiFilterIndicateReceiveComplete(Adapter->Filter.Fddi);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        case NdisMediumLocalTalk:
        case NdisMediumArcnet878_2:
            NdisDprReleaseSpinLock(&Adapter->Lock);
            LtIndicateReceiveComplete(Adapter);
            NdisDprAcquireSpinLock(&Adapter->Lock);
            break;
        default:
            ASSERT(FALSE);
            break;
        }
}
예제 #25
0
파일: st_assoc.c 프로젝트: kcrazy/winekit
VOID 
StaReceiveAssociationResponse(
                             __in  PSTATION                        pStation,
                             __in  PNIC_RX_FRAGMENT                pNicFragment,
                             __in  ULONG                           TotalLength
                             )
{
    NDIS_STATUS         ndisStatus = NDIS_STATUS_SUCCESS;
    PUCHAR              pPacketBuffer;
    PDOT11_MGMT_HEADER  pMgmtHeader;
    PDOT11_ASSOC_RESPONSE_FRAME   pDot11AssocFrame;
    USHORT              StatusCode;
    USHORT              AID = 0;
    PSTA_BSS_ENTRY      pAPEntry = pStation->ConnectContext.ActiveAP;
    BOOLEAN             bTimerCancelled, bSetTxDataRate = FALSE;
    DOT11_RATE_SET      rateSet;

    pPacketBuffer = Hw11GetFragmentDataStart(pNicFragment);

    //
    // Ref to make sure reset/halt does not leave while we are still working
    //
    STA_INCREMENT_REF(pStation->ConnectContext.AsyncFuncCount);

    NdisDprAcquireSpinLock(&(pStation->ConnectContext.Lock));
    if (pStation->ConnectContext.AssociateState == ASSOC_STATE_WAITING_FOR_ASSOCIATE) {
        if (pStation->ConnectContext.ConnectState < CONN_STATE_READY_TO_CONNECT) {
            MpTrace(COMP_ASSOC, DBG_LOUD, ("Reset/Disconnect before association completed\n"));

            //
            // Reset/disconnect, etc. We dont process this associate packet. Eventually, timeout
            // will happen and cleanup
            //
            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
            STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);
            return;
        }

        do {
            if (TotalLength < (sizeof(DOT11_MGMT_HEADER) + sizeof(DOT11_ASSOC_RESPONSE_FRAME))) {
                ndisStatus = NDIS_STATUS_NOT_ACCEPTED;
                MpTrace(COMP_ASSOC, DBG_LOUD, ("Association response packet too short\n"));
                break;
            }

            pMgmtHeader = (PDOT11_MGMT_HEADER)pPacketBuffer;

            //
            // Check that is a packet from the AP we are interested in
            //
            if (!MP_COMPARE_MAC_ADDRESS(pMgmtHeader->SA, pAPEntry->MacAddress) ||
                !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->BSSID, pAPEntry->Dot11BSSID) ||
                !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->DA, Hw11GetMACAddress(pStation->pNic))) {
                ndisStatus = NDIS_STATUS_NOT_ACCEPTED;
                MpTrace(COMP_ASSOC, DBG_LOUD, ("Association response packet not for me\n"));
                break;
            }

        } while (FALSE);

        if (ndisStatus != NDIS_STATUS_NOT_ACCEPTED) {
            //
            // This was a valid response to our association request
            // Complete the association with appropriate status
            //        
            pDot11AssocFrame = (PDOT11_ASSOC_RESPONSE_FRAME)(pPacketBuffer + sizeof(DOT11_MGMT_HEADER));

            //
            // Get association status code from the packet
            //
            StatusCode = pDot11AssocFrame->usStatusCode;

            if (StatusCode == DOT11_FRAME_STATUS_SUCCESSFUL) {
                //
                // Association attempt succeeded
                //
                ndisStatus = NDIS_STATUS_SUCCESS;
                MpTrace(COMP_ASSOC, DBG_NORMAL, ("Association response status SUCCESS\n"));

                //
                // Validate AID
                //
                AID = pDot11AssocFrame->usAID;
                if ((AID & 0xc000) != 0xc000) 
                {
                    // Invalid AID. 
                    pStation->Config.ValidAID = FALSE;
                    
                    // Connecting to a non-conformant AP. Continue with association instead of bailing out.
                    MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association response contains invalid AID %d\n", AID));
                 }
                 else
                 {
                    pStation->Config.ValidAID = TRUE;
                 }
                 
                 AID  &= ~(0xc000);
                 if (AID > 2007) {
                    // AID too big
                    ndisStatus = NDIS_STATUS_FAILURE;
                    MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association response contains invalid AID %d\n", AID));
                 }

                if (ndisStatus == NDIS_STATUS_SUCCESS) {
                    //
                    // Get data rate
                    //
                    ndisStatus = StaGetRateSetFromInfoEle(
                                                         Add2Ptr(pDot11AssocFrame, sizeof(DOT11_ASSOC_RESPONSE_FRAME)),
                                                         TotalLength - sizeof(DOT11_MGMT_HEADER) - sizeof(DOT11_ASSOC_RESPONSE_FRAME),
                                                         FALSE,
                                                         &rateSet);
                }

                if (ndisStatus == NDIS_STATUS_SUCCESS) {
                    // Association has succeeded
                    MpTrace(COMP_ASSOC, DBG_NORMAL, ("Association ID %d\n", AID));

                    pStation->ConnectContext.AssociateState = ASSOC_STATE_RECEIVED_ASSOCIATE;                
                    pStation->Config.AID = AID;

                    //
                    // Clear non-static WEP keys.
                    //
                    Hw11DeleteNonPersistentKey(pStation->pNic);

                    bSetTxDataRate = TRUE;

                    //
                    // Set active PhyId
                    //
                    pStation->Config.ActivePhyId = pAPEntry->PhyId;

                    //
                    // Set multicast cipher algorithm if the exact algorithm was not selected.
                    //
                    if (pStation->Config.MulticastCipherAlgorithmCount > 1) {
                        Hw11SetEncryption(pStation->pNic, FALSE, pStation->Config.MulticastCipherAlgorithm);
                    }
                }
                else {
                    pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION;
                    StatusCode = DOT11_FRAME_STATUS_FAILURE;         // Unspecified failure
                }
            }
            else {
                // The association attempt failed
                MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association failed by the access point with status %d\n", StatusCode));
                pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION;
            }

            //
            // Copy the association response buffer into the AP Entry for completion indication
            //
            NdisDprAcquireSpinLock(&(pAPEntry->Lock));
            pAPEntry->AssocResponseLength = (USHORT)TotalLength;
            MP_ALLOCATE_MEMORY(pStation->MiniportAdapterHandle, &(pAPEntry->pAssocResponse), TotalLength, STA11_MEMORY_TAG);
            if (pAPEntry->pAssocResponse == NULL) {
                MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Unable to save association request packet\n"));
                //
                // We still maintain the association
                //
                pAPEntry->AssocResponseLength = 0;
            }
            else
            {
                //
                // Copy the association response into the packet
                //
                NdisMoveMemory(pAPEntry->pAssocResponse, pPacketBuffer, TotalLength);
            }


            // Save association ID, time, etc
            pAPEntry->AssocID = AID;
            NdisGetCurrentSystemTime(&(pAPEntry->AssociationUpTime));
            pAPEntry->AssocState = dot11_assoc_state_auth_assoc;
            NdisDprReleaseSpinLock(&(pAPEntry->Lock));

            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));

            if (bSetTxDataRate == TRUE)
            {
                //
                // Set data TX rate
                //
                Hw11SetTXDataRate(pStation->pNic, 
                    &rateSet, 
                    Hw11GetCalibratedRSSI(pStation->pNic, pNicFragment)
                    );
            }

            //
            // Attempt to cancel the timer
            //
            /*NdisMCancelTimer(&(pStation->ConnectContext.Timer_AssociateTimeout), &bTimerCancelled); */
            bTimerCancelled = WdfTimerStop(pStation->ConnectContext.Timer_AssociateTimeout, FALSE);
            if (bTimerCancelled) {
                STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);
            }

            if (StatusCode) {
                StaAssociateComplete(pStation, StatusCode | DOT11_ASSOC_STATUS_ASSOCIATION_RESPONSE_START);
            }
            else {
                StaAssociateComplete(pStation, DOT11_ASSOC_STATUS_SUCCESS);
            }
        }
        else {
            NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
        }        
    }
    else {
        NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock));
        MpTrace(COMP_ASSOC, DBG_LOUD, ("Association already timed out\n"));
    }

    STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount);    
}
예제 #26
0
/***************************************************************************
Routine Description:

    A protocol calls the R6040TransferData request (indirectly via
    NdisTransferData) from within its Receive event handler
    to instruct the driver to copy the contents of the received packet
    a specified packet buffer.

Arguments:

    MiniportAdapterContext - Context registered with the wrapper, really
        a pointer to the adapter.

    MiniportReceiveContext - The context value passed by the driver on its call
    to NdisMEthIndicateReceive.  The driver can use this value to determine
    which packet, on which adapter, is being received.

    ByteOffset - An unsigned integer specifying the offset within the
    received packet at which the copy is to begin.  If the entire packet
    is to be copied, ByteOffset must be zero.

    BytesToTransfer - An unsigned integer specifying the number of bytes
    to copy.  It is legal to transfer zero bytes; this has no effect.  If
    the sum of ByteOffset and BytesToTransfer is greater than the size
    of the received packet, then the remainder of the packet (starting from
    ByteOffset) is transferred, and the trailing portion of the receive
    buffer is not modified.

    Packet - A pointer to a descriptor for the packet storage into which
    the MAC is to copy the received packet.

    BytesTransfered - A pointer to an unsigned integer.  The MAC writes
    the actual number of bytes transferred into this location.  This value
    is not valid if the return status is STATUS_PENDING.

Notes:

  - The MacReceiveContext will be a pointer to the open block for
    the packet.
*****************************************************************************/
NDIS_STATUS R6040TransferData(
    OUT PNDIS_PACKET InPacket,
    OUT PUINT BytesTransferred,
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_HANDLE MiniportReceiveContext,
    IN UINT ByteOffset,
    IN UINT BytesToTransfer)
{
    // Variables for the number of bytes to copy, how much can be
    // copied at this moment, and the total number of bytes to copy.
    UINT BytesLeft, BytesNow, BytesWanted;

    // Current NDIS_BUFFER to copy into
    PNDIS_BUFFER CurBuffer;

    PUCHAR BufStart;

    // Address on the adapter to copy from
    const UCHAR *CurCardLoc;

    // Length and offset into the buffer.
    UINT BufLen, BufOff;

    // The adapter to transfer from.
    PR6040_ADAPTER Adapter = ((PR6040_ADAPTER)MiniportReceiveContext);


    //RETAILMSG(R6040DBG, (TEXT("R6040TransferData()\r\n")));

    NdisDprAcquireSpinLock(&Adapter->RcvLock);

    // Add the packet header onto the offset.
    ByteOffset+= R6040_HEADER_SIZE;

    // See how much data there is to transfer.
    if (ByteOffset+BytesToTransfer > Adapter->PacketLen)
    {
        if (Adapter->PacketLen < ByteOffset)
        {
            *BytesTransferred = 0;
            return(NDIS_STATUS_FAILURE);
        }

        BytesWanted = Adapter->PacketLen - ByteOffset;
    }
    else
    {
        BytesWanted = BytesToTransfer;
    }

    // Set the number of bytes left to transfer
    BytesLeft = BytesWanted;
    {
        // Copy data from the card -- it is not completely stored in the
        // adapter structure.
        // Determine where the copying should start.
        CurCardLoc = Adapter->PacketHeaderLoc + ByteOffset;

        // Get location to copy into
        NdisQueryPacket(InPacket, NULL, NULL, &CurBuffer, NULL);
        NdisQueryBuffer(CurBuffer, (PVOID *)&BufStart, &BufLen);

        BufOff = 0;

        // Loop, filling each buffer in the packet until there
        // are no more buffers or the data has all been copied.
        while (CurBuffer && BytesLeft > 0)
        {
            // See how much data to read into this buffer.
            if ((BufLen-BufOff) > BytesLeft)
            {
                BytesNow = BytesLeft;
            }
            else
            {
                BytesNow = (BufLen - BufOff);
            }

            // Copy up the data.
            NdisMoveMemory(BufStart+BufOff,CurCardLoc,BytesNow);

            // Update offsets and counts
            CurCardLoc += BytesNow;
            BytesLeft -= BytesNow;

            // Is the transfer done now?
            if (BytesLeft == 0)
            {
                break;
            }

            // Was the end of this packet buffer reached?
            BufOff += BytesNow;

            if (BufOff == BufLen)
            {
                NdisGetNextBuffer(CurBuffer, &CurBuffer);
                if (CurBuffer == (PNDIS_BUFFER)NULL)
                {
                    break;
                }

                NdisQueryBuffer(CurBuffer, (PVOID *)&BufStart, &BufLen);
                BufOff = 0;
            }
        }

        *BytesTransferred = BytesWanted - BytesLeft;

        NdisDprReleaseSpinLock(&Adapter->RcvLock);
        return(NDIS_STATUS_SUCCESS);
    }

    NdisDprReleaseSpinLock(&Adapter->RcvLock);

    return(NDIS_STATUS_SUCCESS);
}
예제 #27
0
VOID
ReceiverHandleNotification(
    IN  PRECEIVER Receiver
)
/*++
Routine Description:

    Interrupt handler for receive processing
    Put the received packets into an array and call NdisMIndicateReceivePacket
    If we run low on RFDs, allocate another one

Arguments:

    Adapter     Pointer to our adapter

Return Value:

    None
    
--*/
{
    PADAPTER        Adapter = Receiver->Common.Adapter;
    RING_IDX        prod;
    int             more_work;
    PNDIS_PACKET    PacketArray[XENNET_DEF_RFDS];
    NDIS_STATUS     PacketStatus[XENNET_DEF_RFDS];
    UINT            PacketCount;

    if (!RING_HAS_UNCONSUMED_RESPONSES(&Receiver->Common.Ring))
        return;

    NdisDprAcquireSpinLock(&Receiver->Common.Lock);
    if (Receiver->Common.Adapter->media_disconnect) {
        NdisDprReleaseSpinLock(&Receiver->Common.Lock);
        return;
    }

    if (__RING_IDX_DIFFERENCE(Receiver->Common.Ring.req_prod_pvt,
                              Receiver->Common.Ring.sring->rsp_prod) >
        NET_RX_RING_SIZE)
        TraceWarning(("Strange: rsp_prod ahead of req_prod (%d vs %d (s %d))\n",
                      Receiver->Common.Ring.sring->rsp_prod,
                      Receiver->Common.Ring.req_prod_pvt,
                      Receiver->Common.Ring.sring->req_prod));

    PacketCount = 0;

 top:
    prod = Receiver->Common.Ring.sring->rsp_prod;
    XsMemoryBarrier();
    while (!RING_IDXS_EQ(Receiver->Common.Ring.rsp_cons, prod)) {
        PNDIS_PACKET packet;
        ULONG totFrags;
        NDIS_STATUS status;

        status = ReceiverReceivePacket(Receiver, &packet, &totFrags);
        if (status != NDIS_STATUS_SUCCESS)
            continue;

        TraceProfile(("%s(%s, %p)\n", __FUNCTION__, Adapter->XenbusPrefix, packet));

        // See http://msdn.microsoft.com/en-us/library/ms797610.aspx
        if (Receiver->LowResources == 2 ||
            (Receiver->LowResources == 1 && totFrags > 1)) {
            status = NDIS_STATUS_RESOURCES;
            NDIS_SET_PACKET_STATUS(packet, status);
        }

        PacketArray[PacketCount] = packet;
        PacketStatus[PacketCount] = status;
        PacketCount++;

        if (PacketCount == XENNET_DEF_RFDS) {
            ULONG Index;

            Receiver->Common.Frames += PacketCount;
            Receiver->nRxInNdis += PacketCount;

            if (Receiver->nRxInNdis >= Receiver->nRxInNdisMax)
                Receiver->nRxInNdisMax = Receiver->nRxInNdis;

            NdisDprReleaseSpinLock(&Receiver->Common.Lock);
            NdisMIndicateReceivePacket(
                Receiver->Common.Adapter->AdapterHandle,
                PacketArray,
                PacketCount);
            NdisDprAcquireSpinLock(&Receiver->Common.Lock);

            for (Index = 0; Index < PacketCount; Index++) {
                if (PacketStatus[Index] == NDIS_STATUS_RESOURCES) {
                    ReceiverReleasePacket(Receiver, PacketArray[Index]);
                    Receiver->nRxInNdis--;
                } else {
                   XM_ASSERT(PacketStatus[Index] == NDIS_STATUS_SUCCESS);
                }
            }
            PacketCount = 0;

            ReceiverSwizzle(Receiver);
        }
    }
    RING_FINAL_CHECK_FOR_RESPONSES(&Receiver->Common.Ring, more_work);
    if (more_work)
        goto top;

    if (PacketCount != 0) {
        ULONG Index;

        Receiver->Common.Frames += PacketCount;
        Receiver->nRxInNdis += PacketCount;

        if (Receiver->nRxInNdis >= Receiver->nRxInNdisMax)
            Receiver->nRxInNdisMax = Receiver->nRxInNdis;

        NdisDprReleaseSpinLock(&Receiver->Common.Lock);
        NdisMIndicateReceivePacket(
            Receiver->Common.Adapter->AdapterHandle,
            PacketArray,
            PacketCount);
        NdisDprAcquireSpinLock(&Receiver->Common.Lock);

        for (Index = 0; Index < PacketCount; Index++) {
            if (PacketStatus[Index] == NDIS_STATUS_RESOURCES) {
                ReceiverReleasePacket(Receiver, PacketArray[Index]);
                Receiver->nRxInNdis--;
            } else {
                XM_ASSERT(PacketStatus[Index] == NDIS_STATUS_SUCCESS);
            }
        }
        PacketCount = 0;
    }

    // Swizzle unconditionally to make sure we replenish the ring even if
    // nothing was passed to NDIS.
    ReceiverSwizzle(Receiver);

    NdisDprReleaseSpinLock(&Receiver->Common.Lock);
    /* XXX Should maybe adjust size of packet pool from here. */
}
예제 #28
0
// BSS list lock acquired & called at Dispatch
NDIS_STATUS 
HelperPortUpdateBSSEntry(
    __in  PMP_HELPER_PORT        HelperPort,
    __in  PMP_BSS_ENTRY  pBSSEntry,
    __in  PMP_RX_MPDU        pFragment,
    __in  PDOT11_BEACON_FRAME pDot11BeaconPRFrame,
    __in  ULONG           BeaconPRDataLength
    )
{
    NDIS_STATUS         ndisStatus = NDIS_STATUS_SUCCESS;
    PDOT11_MGMT_HEADER  pMgmtPktHeader;
    ULONGLONG           ullHostTimeStamp;
    PVOID               pSavedBeaconPRBuffer = NULL;
    ULONG               uOffsetOfInfoElemBlob = FIELD_OFFSET(DOT11_BEACON_FRAME, InfoElements);
    UCHAR               channel;
    DOT11_PHY_TYPE      PhyType;

    pMgmtPktHeader = (PDOT11_MGMT_HEADER)MP_RX_MPDU_DATA(pFragment);
    NdisGetCurrentSystemTime((PLARGE_INTEGER)&ullHostTimeStamp);
    
    do
    {
        // 
        // Modifying data in the AP entry
        //
        NdisDprAcquireSpinLock(&(pBSSEntry->Lock));

        if (pDot11BeaconPRFrame->Capability.IBSS)
        {
            pBSSEntry->Dot11BSSType = dot11_BSS_type_independent;
        }
        else
        {   
            pBSSEntry->Dot11BSSType = dot11_BSS_type_infrastructure;
        }
        
        //
        // Adhoc station can leave adhoc cell and create a new cell. SoftAPs
        // can move. This means the BSSID can change
        //
        NdisMoveMemory(
            pBSSEntry->Dot11BSSID,
            pMgmtPktHeader->BSSID,
            sizeof(DOT11_MAC_ADDRESS)
            );

        pBSSEntry->HostTimestamp = ullHostTimeStamp;
        pBSSEntry->BeaconTimestamp = pDot11BeaconPRFrame->Timestamp;
        pBSSEntry->BeaconInterval = pDot11BeaconPRFrame->BeaconInterval;
        pBSSEntry->Dot11Capability = pDot11BeaconPRFrame->Capability;
        pBSSEntry->RSSI = pFragment->Msdu->RecvContext.lRSSI;
        pBSSEntry->LinkQuality = pFragment->Msdu->LinkQuality;
        pBSSEntry->ChannelCenterFrequency 
            = pFragment->Msdu->RecvContext.uChCenterFrequency;

        //
        // If signal strength was below our threshold, catch that
        //
        if (pBSSEntry->LinkQuality < HelperPort->RegInfo->RSSILinkQualityThreshold)
        {
            pBSSEntry->LowQualityCount++;
        }
        else
        {
            pBSSEntry->LowQualityCount = 0;
        }

#if 0
        if (pBSSEntry->AssocState == dot11_assoc_state_auth_assoc)
        {
            MpTrace(COMP_ASSOC, DBG_LOUD, ("Received beacon from associated AP: %02X-%02X-%02X-%02X-%02X-%02X\n",
                pMgmtPktHeader->SA[0], pMgmtPktHeader->SA[1], pMgmtPktHeader->SA[2], 
                pMgmtPktHeader->SA[3], pMgmtPktHeader->SA[4], pMgmtPktHeader->SA[5]));
        }
#endif

        //
        // Get channel number at which the frame was received.
        //
        if (Dot11GetChannelForDSPhy(Add2Ptr(pDot11BeaconPRFrame, uOffsetOfInfoElemBlob),
                                    BeaconPRDataLength - uOffsetOfInfoElemBlob, 
                                    &channel) != NDIS_STATUS_SUCCESS)
        {
            channel = pFragment->Msdu->Channel;
        }

        if (channel != 0)
        {
            pBSSEntry->Channel = channel;
        }

        //
        // Get PhyType and PhyId
        //
        PhyType = VNic11DeterminePHYType(HELPPORT_GET_VNIC(HelperPort), 
                                       pBSSEntry->Dot11Capability,
                                       pBSSEntry->Channel);
        if (pBSSEntry->Dot11PhyType != PhyType)
        {
            pBSSEntry->Dot11PhyType = PhyType;
            pBSSEntry->PhyId = BasePortGetPhyIdFromType(HELPPORT_GET_MP_PORT(HelperPort), PhyType);
        }

        if (pMgmtPktHeader->FrameControl.Subtype == DOT11_MGMT_SUBTYPE_BEACON)
        {
            //
            // Increase the beacon frame size if necessary
            //
            if (pBSSEntry->MaxBeaconFrameSize < BeaconPRDataLength)
            {
                MP_ALLOCATE_MEMORY(HELPPORT_GET_MP_PORT(HelperPort)->MiniportAdapterHandle, 
                    &pSavedBeaconPRBuffer, 
                    BeaconPRDataLength,
                    PORT_MEMORY_TAG
                    );
                    
                if (pSavedBeaconPRBuffer == NULL)
                {
                    //
                    // Unable to allocate memory for information elements.
                    // If this is a new AP entry, we wont be adding it to the list.
                    // For existing entries, we end up ignoring the new IE blob
                    //
                    ndisStatus = NDIS_STATUS_RESOURCES;
                    NdisDprReleaseSpinLock(&(pBSSEntry->Lock));
                    break;
                }
                //
                // Delete any old blob buffer
                //
                if (pBSSEntry->pDot11BeaconFrame != NULL)
                {
                    MP_FREE_MEMORY(pBSSEntry->pDot11BeaconFrame);
                }

                pBSSEntry->pDot11BeaconFrame = pSavedBeaconPRBuffer;
                pBSSEntry->MaxBeaconFrameSize = BeaconPRDataLength;
            }

            // Update the beacon
            pBSSEntry->BeaconFrameSize = BeaconPRDataLength;
            
            // Also save this as the IE blob pointer
            pBSSEntry->InfoElemBlobSize = BeaconPRDataLength - uOffsetOfInfoElemBlob;
            pBSSEntry->pDot11InfoElemBlob = (PUCHAR)pBSSEntry->pDot11BeaconFrame + uOffsetOfInfoElemBlob;
            
            //
            // Update/Save the beacon information element block
            //
            NdisMoveMemory(
                pBSSEntry->pDot11BeaconFrame,
                pDot11BeaconPRFrame,
                BeaconPRDataLength
                );
        }
    
        if (pMgmtPktHeader->FrameControl.Subtype == DOT11_MGMT_SUBTYPE_PROBE_RESPONSE)
        {
            //
            // Increase the probe response frame size if necessary
            //
            if (pBSSEntry->MaxProbeFrameSize < BeaconPRDataLength)
            {
                MP_ALLOCATE_MEMORY(HELPPORT_GET_MP_PORT(HelperPort)->MiniportAdapterHandle, 
                    &pSavedBeaconPRBuffer, 
                    BeaconPRDataLength,
                    PORT_MEMORY_TAG
                    );
                    
                if (pSavedBeaconPRBuffer == NULL)
                {
                    //
                    // Unable to allocate memory for information elements.
                    // If this is a new AP entry, we wont be adding it to the list.
                    // For existing entries, we end up ignoring the new IE blob
                    //
                    ndisStatus = NDIS_STATUS_RESOURCES;
                    NdisDprReleaseSpinLock(&(pBSSEntry->Lock));
                    break;
                }
                //
                // Delete any old blob buffer
                //
                if (pBSSEntry->pDot11ProbeFrame != NULL)
                {
                    MP_FREE_MEMORY(pBSSEntry->pDot11ProbeFrame);
                }

                pBSSEntry->pDot11ProbeFrame = pSavedBeaconPRBuffer;
                pBSSEntry->MaxProbeFrameSize = BeaconPRDataLength;
            }
            
            pBSSEntry->ProbeFrameSize = BeaconPRDataLength;

            // Also save this as the IE blob pointer
            pBSSEntry->InfoElemBlobSize = BeaconPRDataLength - uOffsetOfInfoElemBlob;
            pBSSEntry->pDot11InfoElemBlob = (PUCHAR)pBSSEntry->pDot11ProbeFrame + uOffsetOfInfoElemBlob;

            //
            // Update/Save the beacon information element block
            //
            NdisMoveMemory(
                pBSSEntry->pDot11ProbeFrame,
                pDot11BeaconPRFrame,
                BeaconPRDataLength
                );

        }

#if 0
        if (pBSSEntry->AssocState == dot11_assoc_state_auth_assoc)
        {
            MpTrace(COMP_SCAN, DBG_LOUD, ("Received %d for AP %02X-%02X-%02X-%02X-%02X-%02X \n", 
                    pMgmtPktHeader->FrameControl.Subtype,
                    pBSSEntry->Dot11BSSID[0], pBSSEntry->Dot11BSSID[1], pBSSEntry->Dot11BSSID[2], 
                    pBSSEntry->Dot11BSSID[3], pBSSEntry->Dot11BSSID[4], pBSSEntry->Dot11BSSID[5]));
        }
#endif

        //
        // Done with our modification of the AP entry
        //
        NdisDprReleaseSpinLock(&(pBSSEntry->Lock));
        
    } while (FALSE);

    return ndisStatus;