Esempio n. 1
0
void
CAR6KMini::IndicateReceivePackets()
//
//  This function is called on the worker thread to indicate received
//  packets.
//
{
	NDIS_PACKET *pPacket;
	NDIS_PACKET *PacketArray[MAX_PACKETS_PER_INDICATE];
	ULONG        NumPacketsToIndicate;
	LIST_ENTRY  *pNode;
	boolean      bEventSignalled;

	NdisResetEvent(&m_RxWorkItemExitedEvent);

	while (false == m_Halting)
	{
		// Wait for packets to be placed on the list
		bEventSignalled = NdisWaitEvent(&m_RxPendingEvent, 0);
		if (m_Halting || !bEventSignalled)
			break;

		NumPacketsToIndicate = 0;

		//
		// Get up to MAX_PACKET_PER_INDICATE packets from the RxPending list.
		// Put the packet pointers into an array.
		//
		Lock();
		while (!IsListEmpty(&m_RxPendingPacketList))
		{
			pNode = RemoveHeadList(&m_RxPendingPacketList);
			pPacket = (PNDIS_PACKET)((PBYTE)pNode - offsetof(NDIS_PACKET, MiniportReserved));
			PacketArray[NumPacketsToIndicate++] = pPacket;
			if (NumPacketsToIndicate == MAX_PACKETS_PER_INDICATE) {
				Unlock();
				NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, NumPacketsToIndicate);
				Lock();
				NumPacketsToIndicate = 0;
			}
		}
		NdisResetEvent(&m_RxPendingEvent);
		Unlock();

		//
		// Indicate the received packets up to protocol drivers bound to us.
		//
		if (NumPacketsToIndicate)
			NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, NumPacketsToIndicate);
	}

	NdisSetEvent(&m_RxWorkItemExitedEvent);
}
Esempio n. 2
0
/*
NicIndicateRecvPackets indicate received packet (MAC frame) to NDIS 
(then protocol stack)

Parameters:
    pAdapter       : pointer to adapter object created by miniport driver.
    ppNBSPackets   : pointer to an NDIS packet to be indicated up.
      
Return:  

Note: 

History:    Created by yichen, 1/Apr/2009

IRQL: PASSIVE_LEVEL
*/
VOID NicIndicateRecvPackets(IN PMP_ADAPTER pAdapter,IN PPNDIS_PACKETS_OR_NBL ppNBSPackets)
{
    NDIS_SET_PACKET_HEADER_SIZE(*ppNBSPackets, ETH_HEADER_SIZE);
    NDIS_SET_PACKET_STATUS(*ppNBSPackets, NDIS_STATUS_SUCCESS);
    NdisMIndicateReceivePacket(pAdapter->AdapterHandle, ppNBSPackets, 1); //only 1 packet indicated
    InterlockedIncrement64(&pAdapter->ullGoodReceives);
}
Esempio n. 3
0
NTSTATUS
MPIndicatePacket(PHWT_ADAPTER Adapter, PVOID Input, ULONG InputSize, PDEV_RET Output, ULONG OutputSize, PIRP Irp) {

	PVOID data = NULL;
	NDIS_STATUS ndis_status = NDIS_STATUS_FAILURE;
	PNDIS_BUFFER ndis_buffer = NULL;
	PNDIS_PACKET ndis_packet = NULL;	
	do {
		data = ExAllocatePoolWithTag(NonPagedPool, InputSize, 'tkpi');

		RtlCopyMemory(data, Input, InputSize);
				
		NdisAllocateBuffer(&ndis_status, 
                           &ndis_buffer, 
                           Adapter->AllocateBufferPool,
                           data,
                           InputSize);
		if (ndis_status != NDIS_STATUS_SUCCESS)
			break;

		NdisAllocatePacket(&ndis_status,
                           &ndis_packet,
                           Adapter->AllocatePacketPool);
		if (ndis_status != NDIS_STATUS_SUCCESS)
			break;

		NdisReinitializePacket(ndis_packet);
		*(PVOID*)ndis_packet->MiniportReserved = data;
		NdisChainBufferAtBack(ndis_packet, ndis_buffer);
		NDIS_SET_PACKET_HEADER_SIZE(ndis_packet, sizeof(ETHERNET_HEADER));
		NDIS_SET_PACKET_STATUS(ndis_packet, NDIS_STATUS_SUCCESS);
		NdisMIndicateReceivePacket(Adapter->AdapterHandle, &ndis_packet, 1);

		Output->hResult = S_OK;

		ndis_status = NDIS_STATUS_SUCCESS;
	} while(FALSE);
	
	if (ndis_status != NDIS_STATUS_SUCCESS &&
		ndis_status != STATUS_PENDING) {
		if (ndis_packet)
			NdisFreePacket(ndis_packet);
		if (ndis_buffer) 
			NdisFreeBuffer(ndis_buffer);		
		if (data)
			ExFreePoolWithTag(data, 'tkpi');
	}
	return ndis_status;
}
Esempio n. 4
0
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);
                  
}
Esempio n. 5
0
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{}

}
Esempio n. 6
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. */
}
/*----------------------------------------------------------------------------*/
WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_32 ucPktNum)
{
	NDIS_STATUS arStatus[CFG_RX_MAX_PKT_NUM];
	UINT_32 u4Idx;

	for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) {
		UINT_32 i, pivot;
		PVOID pvTmp;

		if (NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[u4Idx]) == NDIS_STATUS_RESOURCES) {
			pivot = u4Idx;
			for (i = u4Idx + 1; i < ucPktNum; i++) {
				if (NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[i]) !=
				    NDIS_STATUS_RESOURCES) {
					pvTmp = apvPkts[pivot];
					apvPkts[pivot] = apvPkts[i];
					apvPkts[i] = pvTmp;
					pivot++;
				}
			}
			break;
		}
	}

	for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) {
		arStatus[u4Idx] = NDIS_GET_PACKET_STATUS((PNDIS_PACKET) apvPkts[u4Idx]);
		if (arStatus[u4Idx] == NDIS_STATUS_SUCCESS) {
			/* 4 Increase the Pending Count before calling NdisMIndicateReceivePacket(). */
			InterlockedIncrement(&prGlueInfo->i4RxPendingFrameNum);
		}
	}

	NdisMIndicateReceivePacket(prGlueInfo->rMiniportAdapterHandle,
				   (PPNDIS_PACKET) apvPkts, (UINT) ucPktNum);

	for (u4Idx = 0; u4Idx < ucPktNum; u4Idx++) {

		/* 4 <1> Packets be retained. */
		if (arStatus[u4Idx] != NDIS_STATUS_SUCCESS) {
			PNDIS_PACKET prNdisPacket = (PNDIS_PACKET) apvPkts[u4Idx];
			PNDIS_BUFFER prNdisBuf = (PNDIS_BUFFER) NULL;

			ASSERT(prNdisPacket);

			NdisUnchainBufferAtBack(prNdisPacket, &prNdisBuf);

			if (prNdisBuf) {
				NdisFreeBuffer(prNdisBuf);
			}
#if DBG
			else {
				ASSERT(0);
			}
#endif				/* DBG */

			/* Reinitialize the packet descriptor for reuse. */
			NdisReinitializePacket(prNdisPacket);

#if CETK_NDIS_PERFORMANCE_WORKAROUND
			{
				PUINT_32 pu4Dummy;
				pu4Dummy = (PUINT_32) prNdisPacket->ProtocolReserved;
				*pu4Dummy = 0;
			}
#endif				/* CETK_NDIS_PERFORMANCE_WORKAROUND */

		}
	}

	return WLAN_STATUS_SUCCESS;
}				/* kalIndicatePackets */
Esempio n. 8
0
/*
 *************************************************************************
 *  DeliverFullBuffers
 *************************************************************************
 *
 *  Deliver received packets to the protocol.
 *
 */
VOID DeliverFullBuffers(IrDevice *thisDev)
{
	int rcvBufIndex = thisDev->firstRcvBufIndex;

	DBGOUT(("==> DeliverFullBuffers"));



	/*
	 *  Deliver all full rcv buffers
	 */
	while (rcvBufIndex != NO_BUF_INDEX){
		rcvBuffer *rcvBuf = &thisDev->rcvBufs[rcvBufIndex];
		NDIS_STATUS stat;
		PNDIS_BUFFER packetBuf;
		SLOW_IR_FCS_TYPE fcs;

		switch (rcvBuf->state){

			case STATE_FREE:
			case STATE_PENDING:
				/*
				 *  This frame was already delivered.  Just go to the next one.
				 */
				break;
		
			case STATE_FULL:

				/*
				 *  The packet we have already has had BOFs, EOF, and
				 *  escape-sequences removed.  
				 *  It contains an FCS code at the end,
				 *  which we need to verify and then remove before
				 *  delivering the frame.
				 *  We compute the FCS on the packet with the packet FCS
				 *  attached; this should produce the constant value GOOD_FCS.
				 */
				fcs = ComputeFCS(rcvBuf->dataBuf, rcvBuf->dataLen);

				if (fcs != GOOD_FCS){
					/*
					 *  FCS Error.  Drop this frame.
					 */
					DBGERR(("Bad FCS in DeliverFullBuffers 0x%x!=0x%x.", (UINT)fcs, (UINT)GOOD_FCS));
					rcvBuf->state = STATE_FREE;

					DBGSTAT(("Dropped %d/%d packets; packet with BAD FCS (%xh!=%xh):", 
							++thisDev->packetsDropped, thisDev->packetsDropped + thisDev->packetsRcvd, fcs, GOOD_FCS));
					DBGPRINTBUF(rcvBuf->dataBuf, rcvBuf->dataLen);
					break;
				}


				/*
				 *  Remove the FCS from the end of the packet.
				 */
				rcvBuf->dataLen -= SLOW_IR_FCS_SIZE;


				#ifdef DBG_ADD_PKT_ID
					if (addPktIdOn){
						/*
						 *  Remove dbg packet id.
						 */
						rcvBuf->dataLen -= sizeof(USHORT);
						DBGOUT((" RCVing packet %xh **", (UINT)*(USHORT *)(rcvBuf->dataBuf+rcvBuf->dataLen)));
					}
				#endif

				/*
				 *  The packet array is set up with its NDIS_PACKET.
				 *  Now we need to allocate a single NDIS_BUFFER for the
				 *  NDIS_PACKET and set the NDIS_BUFFER  to the part of dataBuf
				 *  that we want to deliver.
				 */
				NdisAllocateBuffer(	&stat, 
									&packetBuf, 
									thisDev->bufferPoolHandle,
									(PVOID)rcvBuf->dataBuf,
									rcvBuf->dataLen); 
				if (stat != NDIS_STATUS_SUCCESS){
					DBGERR(("NdisAllocateBuffer failed"));
					break;
				}
				NdisChainBufferAtFront(rcvBuf->packet, packetBuf);

				/*
				 *  Fix up some other packet fields.
				 */
				NDIS_SET_PACKET_HEADER_SIZE(rcvBuf->packet, SLOW_IR_ADDR_SIZE + SLOW_IR_CONTROL_SIZE);

				DBGPKT(("Indicating rcv packet 0x%x.", (UINT)rcvBuf->packet));
				DBGPRINTBUF(rcvBuf->dataBuf, rcvBuf->dataLen);

				/*  
				 *  Indicate to the protocol that another packet is ready.  
				 *  Set the rcv buffer's state to PENDING first to avoid
				 *  a race condition with NDIS's call to the return packet
				 *  handler.
				 */
				rcvBuf->state = STATE_PENDING;
				NdisMIndicateReceivePacket(thisDev->ndisAdapterHandle, &rcvBuf->packet, 1);
				stat = NDIS_GET_PACKET_STATUS(rcvBuf->packet);			
				if (stat == NDIS_STATUS_PENDING){
					/*
					 *  The packet is being delivered asynchronously.
					 *  Leave the rcv buffer's state as PENDING; we'll
					 *  get a callback when the transfer is complete.
					 *	
					 *  Do NOT step firstRcvBufIndex.
					 *  We don't really need to break out here, 
					 *  but we will anyways just to make things simple.
					 *  This is ok since we get this deferred interrupt callback
					 *  for each packet anyway.  It'll give the protocol a chance
					 *  to catch up.
					 */
					DBGSTAT(("Rcv Pending.  Rcvd %d packets", ++thisDev->packetsRcvd));
				}
				else {
					/*
					 *  If there was an error, we are dropping this packet;
					 *  otherwise, this packet was delivered synchronously. 
					 *  We can free the packet buffer and make this rcv frame
					 *  available.
					 */
					NdisUnchainBufferAtFront(rcvBuf->packet, &packetBuf);
					if (packetBuf){
						NdisFreeBuffer(packetBuf);	
					}	
					rcvBuf->state = STATE_FREE;

					if (stat == NDIS_STATUS_SUCCESS){
						DBGSTAT(("Rcvd %d packets", ++thisDev->packetsRcvd));
					}
					else {
						DBGSTAT(("Dropped %d/%d rcv packets. ", thisDev->packetsDropped++, thisDev->packetsDropped+thisDev->packetsRcvd));
					}
				}

				break;


			default:
				/*
				 *  This should never happen.
				 */
				DBGERR(("Bad rcv buffer state in DPC"));
				break;
		}
		
		/*
		 *  Step the buffer index
		 */
		if (rcvBufIndex == thisDev->lastRcvBufIndex){
			rcvBufIndex = NO_BUF_INDEX;
		}
		else {
			rcvBufIndex = NEXT_RCV_BUF_INDEX(rcvBufIndex);
		}
	}

	DBGOUT(("<== DeliverFullBuffers"));

}
Esempio n. 9
0
NTSTATUS
divert_write(
    IN PDEVICE_OBJECT       pDeviceObject,
    IN PIRP                 pIrp
    )
{
	int rc = STATUS_SUCCESS;
	PNDIS_PACKET pNdisPacket;
	PADAPT pa = _pa, pa2; // XXX
	NDIS_STATUS status;
	PIO_STACK_LOCATION pIrpSp;
	NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;

	pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

	if (pIrp->MdlAddress == NULL) {
		rc = STATUS_INSUFFICIENT_RESOURCES;
		goto Out;
	}

	if (!(pEthHeader = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,
					  		NormalPagePriority))) {
		rc = STATUS_INSUFFICIENT_RESOURCES;
		goto Out;
	}

	lock();

	NdisAllocatePacket(&status, &pNdisPacket, _packet_pool);

	unlock();

	if (status != STATUS_SUCCESS) {
		rc = STATUS_INSUFFICIENT_RESOURCES;
		goto Out;
	}

	NdisChainBufferAtFront(pNdisPacket, pIrp->MdlAddress);

	if ((pa2 = get_pa(pEthHeader->SrcAddr))) {
		NdisSendPackets(pa2->BindingHandle, &pNdisPacket, 1);
	} else {
		pa2 = get_pa(pEthHeader->DstAddr);
		if (pa2)
			pa = pa2;

		NDIS_SET_PACKET_STATUS(pNdisPacket, NDIS_STATUS_RESOURCES);
		NdisMIndicateReceivePacket(pa->MiniportHandle, &pNdisPacket, 1);
		NdisFreePacket(pNdisPacket);
	}

	rc = STATUS_PENDING;
	rc = STATUS_SUCCESS;

Out:
	pIrp->IoStatus.Status = rc;

	if (rc != STATUS_PENDING) {
		pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
        	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}

	return rc;
}
Esempio n. 10
0
// Process the received packet
void NeoWrite(void *buf)
{
	UINT num, i, size;
	void *packet_buf;
	// Validate arguments
	if (buf == NULL)
	{
		return;
	}

	// Number of packets
	num = NEO_NUM_PACKET(buf);
	if (num > NEO_MAX_PACKET_EXCHANGE)
	{
		// Number of packets is too many
		return;
	}
	if (num == 0)
	{
		// No packet
		return;
	}

	if (ctx->Halting != FALSE)
	{
		// Halting
		return;
	}

	if (ctx->Opened == FALSE)
	{
		// Not connected
		return;
	}

	for (i = 0;i < num;i++)
	{
		PACKET_BUFFER *p = ctx->PacketBuffer[i];

		size = NEO_SIZE_OF_PACKET(buf, i);
		if (size > NEO_MAX_PACKET_SIZE)
		{
			size = NEO_MAX_PACKET_SIZE;
		}
		if (size < NEO_PACKET_HEADER_SIZE)
		{
			size = NEO_PACKET_HEADER_SIZE;
		}

		packet_buf = NEO_ADDR_OF_PACKET(buf, i);

		// Buffer copy
		NeoCopy(p->Buf, packet_buf, size);

		if (g_is_win8 == false)
		{
			// Adjust the buffer size
			NdisAdjustBufferLength(p->NdisBuffer, size);
			// Set the packet information
			NDIS_SET_PACKET_STATUS(p->NdisPacket, NDIS_STATUS_RESOURCES);
			NDIS_SET_PACKET_HEADER_SIZE(p->NdisPacket, NEO_PACKET_HEADER_SIZE);
		}
		else
		{
			NdisMEthIndicateReceive(ctx->NdisMiniport, ctx, 
				p->Buf, NEO_PACKET_HEADER_SIZE,
				((UCHAR *)p->Buf) + NEO_PACKET_HEADER_SIZE, size - NEO_PACKET_HEADER_SIZE,
				size - NEO_PACKET_HEADER_SIZE);
			NdisMEthIndicateReceiveComplete(ctx->NdisMiniport);
		}
	}

	// Notify that packets have received
	ctx->Status.NumPacketRecv += num;

	if (g_is_win8 == false)
	{
		NdisMIndicateReceivePacket(ctx->NdisMiniport, ctx->PacketBufferArray, num);
	}
}
Esempio n. 11
0
/*--------------------------------------------------------------------------
  ssh_interceptor_send()
  
  Sends packet either down to the network or up to the protocol.
  --------------------------------------------------------------------------*/
void
ssh_interceptor_send(SshInterceptor interceptor,
                     SshInterceptorPacket ip,
                     size_t media_header_len)
{
  SshNdisPacket packet;
  ULONG first_buf_len = SSH_ETHERH_HDRLEN;
  SshNdisIMAdapter adapter;
  SshCpuContext cpu_ctx;
  Boolean use_one_buffer = FALSE;
  ULONG new_value;

  /* Sanity checks for arguments */
  SSH_ASSERT(interceptor != NULL);
  SSH_ASSERT(ip != NULL);
  SSH_ASSERT((ip->flags & SSH_PACKET_FROMADAPTER) !=
              (ip->flags & SSH_PACKET_FROMPROTOCOL));
#ifndef _WIN32_WCE
  SSH_ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
#endif /* _WIN32_WCE */

  cpu_ctx = &interceptor->cpu_ctx[ssh_kernel_get_cpu()];

  packet = CONTAINING_RECORD(ip, SshNdisPacketStruct, ip);

#ifdef DEBUG_LIGHT
  packet->f.flags.in_engine = 0;
#endif /* DEBUG_LIGHT */

  adapter = (SshNdisIMAdapter)packet->adapter_in;

  /* Check if adapter where the packet should be sent is
     different where the packet originated from */
  if (adapter && (adapter->ifnum == ip->ifnum_out))
    {
      new_value = InterlockedIncrement(&adapter->ref_count);
      packet->adapter_out = (SshAdapter)adapter;
    }
  else
    {
      SshAdapter gen_adapter = NULL;

      if (ip->ifnum_out < SSH_INTERCEPTOR_MAX_ADAPTERS)
        {
          ssh_kernel_rw_mutex_lock_read(&interceptor->adapter_lock);
          gen_adapter = interceptor->adapter_table[ip->ifnum_out];
          if (gen_adapter)
            {
              new_value = InterlockedIncrement(&gen_adapter->ref_count);
              packet->adapter_out = gen_adapter;
            }
          ssh_kernel_rw_mutex_unlock_read(&interceptor->adapter_lock);
        }

      if (gen_adapter == NULL)
        goto free_packet;

      adapter = (SshNdisIMAdapter)gen_adapter;
    }
  SSH_ASSERT(new_value > 0);

  /* Check that active adapter found and it supports the protocol */
  if (!ssh_adapter_is_enabled((SshNdisIMAdapter)adapter))
    {
      SSH_DEBUG(SSH_D_FAIL, ("active network connection not found"));
      goto free_packet;
    }

#ifndef _WIN32_WCE
  /* Check if packet is plain IPv4 (IPv6) and then add ethernet framing */
  if (ip->protocol == SSH_PROTOCOL_IP4 || ip->protocol == SSH_PROTOCOL_IP6)
    {
      if (!ssh_wan_packet_encapsulate((SshAdapter)adapter, ip))
        {
          SSH_DEBUG(SSH_D_FAIL, ("packet framing failed"));
          goto free_packet;
        }

      /* Some dial-up drivers seem to expect to receive whole packet in one
         NDIS buffer. */
      if (ip->flags & SSH_PACKET_FROMADAPTER)
        use_one_buffer = TRUE;
    }
#endif /* _WIN32_WCE */

  /* Add the VLAN tagging, if any */
  if (packet->vlan_tag_count > 0)
    {
      if (adapter != (SshNdisIMAdapter)packet->adapter_in)
        {
          /* Engine forwards this packet to different interface. Check 
             whether this is VLAN/QoS enabled interface and reconstruct
             tagging accordingly. */

          switch (adapter->options 
                  & (NDIS_MAC_OPTION_8021Q_VLAN
                     | NDIS_MAC_OPTION_8021P_PRIORITY))
            {
            case 0:
              /* Adapter doesn't support IEEE 802.1q/p; drop VLAN tag(s). */
              packet->vlan_tag_count = 0;
              break;

            case NDIS_MAC_OPTION_8021P_PRIORITY:
              /* Adapter supports only priority (QoS) tagging. */
              packet->vlan_tags[0].vlan_id = 0;
              packet->vlan_tag_count = 1;
              break;

            default:
              /* Adapter supports also VLAN. Change the VLAN ID of the
                 first tag to the one configued to this NIC driver. */
              packet->vlan_tags[0].vlan_id = adapter->vlan_id;
              break;
            }
        }

      if (packet->vlan_tag_count)
        {
          unsigned char *vlan_tags;
          SshUInt16 i;

          vlan_tags = 
            ssh_interceptor_packet_insert(ip, SSH_ETHERH_OFS_TYPE,
                                          packet->vlan_tag_count * 4);
          if (vlan_tags == NULL)
            {
              SSH_DEBUG(SSH_D_FAIL, ("Failed to add VLAN tags"));
              return;
            }

          for (i = 0; i < packet->vlan_tag_count; i++)
            {
              unsigned char *tag = vlan_tags + (i * 4);

              SSH_PUT_16BIT(tag, SSH_ETHERTYPE_VLAN);
              SSH_PUT_16BIT((tag + 2), 
                            (packet->vlan_tags[i].vlan_id << 4
                            | packet->vlan_tags[i].qos));
            }
        }
    }

  NDIS_SET_PACKET_HEADER_SIZE(packet->np, SSH_ETHERH_HDRLEN);
  NDIS_SET_PACKET_STATUS(packet->np, NDIS_STATUS_SUCCESS);

#ifdef _WIN32_WCE
  if (adapter->media == NdisMediumWan)
    {
      if (ip->flags & SSH_PACKET_FROMPROTOCOL)
        {
          if (!ssh_wan_send_to_adapter(adapter, packet, ip->protocol))
            SSH_DEBUG(SSH_D_FAIL, ("Cannot send packet to WAN adapter"));
        }
      else if (ip->flags & SSH_PACKET_FROMADAPTER)
        {
          if (!ssh_wan_send_to_protocol(adapter, packet, ip->protocol))
            SSH_DEBUG(SSH_D_FAIL, ("Cannot send packet to WAN protocol"));
        }
      else
        {
          SSH_DEBUG(SSH_D_ERROR, ("Dropping WAN packet without direction"));
        }
      ssh_interceptor_packet_free(&packet->ip);
      return;
    }
#endif /* _WIN32_WCE */

  if (ip->flags & SSH_PACKET_FROMPROTOCOL)
    {
      NDIS_STATUS status;

      /* Send packet to network */
      NdisSetPacketFlags(packet->np, NDIS_FLAGS_DONT_LOOPBACK);

      if (cpu_ctx->in_packet_cb 
	  || cpu_ctx->in_route_cb
	  || cpu_ctx->in_timeout_cb)
        {
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Risk for recursive call; enqueueing packet 0x%p",
                     packet));

#ifdef DEBUG_LIGHT
          packet->f.flags.in_send_queue = 1;
#endif /* DEBUG_LIGHT */
	  if (cpu_ctx->in_packet_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->send_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_send_queue = 1;
	    }
	  else if (cpu_ctx->in_route_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->route_send_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_route_send_queue = 1;
	    }
	  else if (cpu_ctx->in_timeout_cb)
	    {
	      ssh_net_packet_enqueue(
                             &cpu_ctx->timeout_send_queue[adapter->ifnum],
			     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_timeout_send_queue = 1;
	    }
        }
      else
        {
#ifdef DEBUG_LIGHT
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Sending packet 0x%p to underlying driver",
                     packet));

          packet->f.flags.in_miniport = 1;
#endif /* DEBUG_LIGHT */
          NdisSend(&status, adapter->binding_handle, packet->np);

          if (status != NDIS_STATUS_PENDING)
            {
              SSH_DEBUG(SSH_D_NICETOKNOW,
                        ("Send operation completed synchronously; "
                         "packet=0x%p, status=%@",
                         ssh_ndis_status_render, status));
              ssh_interceptor_packet_free(&packet->ip);
            }
        }
    }
  else if (ip->flags & SSH_PACKET_FROMADAPTER)
    {
      /* Packet is ready now so check packet consistency */
      if (use_one_buffer)
        first_buf_len = packet->packet_len;
      else
        first_buf_len += adapter->lookahead_size;
      first_buf_len = MIN(first_buf_len, packet->packet_len);
        
      if (!ssh_packet_get_contiguous_data((SshNetDataPacket)packet, 
                                          0, first_buf_len, FALSE))
        {
          SSH_DEBUG(SSH_D_FAIL, ("Invalid packet"));
          goto free_packet;
        }

      if (cpu_ctx->in_packet_cb
	  || cpu_ctx->in_route_cb
	  || cpu_ctx->in_timeout_cb)
        {
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Risk for recursive call; enqueueing packet 0x%p",
                     packet));

#ifdef DEBUG_LIGHT
          packet->f.flags.in_recv_queue = 1;
#endif /* DEBUG_LIGHT */
	  if (cpu_ctx->in_packet_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->recv_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_recv_queue = 1;
	    }
	  else if (cpu_ctx->in_route_cb)
	    {
	      ssh_net_packet_enqueue(&cpu_ctx->route_recv_queue[adapter->ifnum],
				     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_route_recv_queue = 1;
	    }
	  else if (cpu_ctx->in_timeout_cb)
	    {
	      ssh_net_packet_enqueue(
			     &cpu_ctx->timeout_recv_queue[adapter->ifnum],
			     (SshNetDataPacket)packet);
	      cpu_ctx->packets_in_timeout_recv_queue = 1;
	    }
        }
      else
        {
          SSH_DEBUG(SSH_D_NICETOKNOW, 
                    ("Indicating packet 0x%p to upper layers",
                     packet));

#ifdef DEBUG_LIGHT
          packet->f.flags.in_protocol = 1;
#endif /* DEBUG_LIGHT */
          NdisMIndicateReceivePacket(adapter->handle, &packet->np, 1);
        }
    }
  else
    {
      SSH_NOTREACHED;
    }

  return;

 free_packet:
  /* Otherwise just drop the packet */
  SSH_DEBUG(SSH_D_FAIL, ("ssh_interceptor_send(): dropping packet"));
  ssh_interceptor_packet_free(&packet->ip);
}
Esempio n. 12
0
void
CAR6KMini::ReceiveWMIDataPacket(
	HTC_EVENT_INFO  *evInfo)
//
//  This function processes data from an HTC_BUFFER_RECEIVED indication
//  not on the WMI_CONTROL_MBOX endpoint.
//
{
	ndis_mini_buf_t *pb = (ndis_mini_buf_t *)evInfo->cookie;
	NDIS_STATUS      Status;
	NDIS_PACKET     *pPacket;
	NDIS_BUFFER     *pBuffer;
	PBYTE            pData;
	ULONG            cbData;
	BOOL			 doDix = FALSE;
	USHORT			 etherType;
	SNAP_HEADER		 *pSnapHdr;
	MAC_ADDRESS		 *pDestAddr,*tempAddr;
	BOOL			 mcForUs = FALSE;
		
	
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "AR6K: +ReceiveWMIDataPacket");

	    
    if (evInfo->status != A_OK) {
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket Error in receiving : status = %x\n", evInfo->status);
		if (A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
    }
    
	// evInfo->actualLength is the length of the pb->data including
	//      2 bytes: WMI_DATA_HEADER [optional - only if HTC header is 46 00]
	//     14 bytes: 802.3 MAC header
	//      8 bytes: SNAP header (with EthType as last 2 bytes)
	//      N bytes: payload (e.g. IP packet)
	pData = evInfo->buffer; 
	cbData = evInfo->actualLength;

	// Remove the WMI_DATA_HDR.
	if (cbData < sizeof(WMI_DATA_HDR))
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket missing WMI header (%u bytes)\n", evInfo->actualLength);
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
    }
	pData += sizeof(WMI_DATA_HDR);
	cbData -= sizeof(WMI_DATA_HDR);

	if (cbData < sizeof(ETHERNET_MAC_HEADER) + sizeof(SNAP_HEADER))
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket missing MAC + SNAP (%u bytes)\n", cbData);
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
	}

#ifdef WMM
	Lock();
    wmi_implicit_create_pstream((wmi_t *)m_pWMI, pb, DNLINK_TRAFFIC,1);
	Unlock();
#endif //WMM

	
	pDestAddr=(MAC_ADDRESS *)pData;
 	
 	/* Apply NDIS receive filter */
     if (isGrp(pDestAddr)) {
         if (isBcast(pDestAddr)) {
			 if (!(m_CurrentPacketFilter & NDIS_PACKET_TYPE_BROADCAST)) {
                 if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
					a_netbuf_free(pb);
				 }			
				 goto done;
             }
         } else {
			 isMcForUs(pDestAddr,&mcForUs);
			 if (!(m_CurrentPacketFilter & (NDIS_PACKET_TYPE_MULTICAST |
				 NDIS_PACKET_TYPE_ALL_MULTICAST)) || !(mcForUs))
             {
				 if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
					a_netbuf_free(pb);
				 }
				 goto done;
             }
		}
 		
     } else {
		tempAddr=(MAC_ADDRESS *) m_PermanentAddress;
		if ((A_MACADDR_COMP(pDestAddr,tempAddr) != 0) &&
             !(m_CurrentPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
        {
			if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
				a_netbuf_free(pb);
			}
			goto done;
        }
	}

	 // Allocate an NDIS_PACKET from our packet pool.
	NdisAllocatePacket(&Status, &pPacket, m_RxPacketPool);
	if (NDIS_STATUS_SUCCESS != Status)
	{
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - NdisAllocatePacket failed\n");
		if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT2, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
			a_netbuf_free(pb);
		}
		goto done;
	}

	// Check for ethernetType in SNAP header for NOVELL_IPX, APPLE_TALK_ARP etc
	// remove 802.3 length and SNAP header if it is not of these types 
	
	pSnapHdr=(SNAP_HEADER *)(pData+sizeof(ETHERNET_MAC_HEADER));
	etherType=A_BE2CPU16(pSnapHdr->Type);
	
	doDix=((A_MEMCMP(pSnapHdr,&bridgeTunnel, sizeof(CAP_CONST))) == 0);
	if((!doDix) && ((A_MEMCMP(pSnapHdr,&vrfc1042, sizeof(CAP_CONST))) == 0))
	{
		doDix = ((etherType != APPLE_TALK_ARP) && (etherType != NOVELL_IPX));
	}
	// Get rid of the 802.3 length and SNAP header by copying
	// the 802.3 DestMACAddr and SrcMACAddr forward so they
	// immediately precede the EthType at the end of the SNAP header.
	// That gives us a DIX packet.

	if (doDix) {
	memmove(pData + sizeof(SNAP_HEADER), pData, ETHERNET_MAC_ADDRESS_LENGTH * 2);
	pData += sizeof(SNAP_HEADER);
	cbData -= sizeof(SNAP_HEADER);
	}


	

	// Setup the fields of NDIS_BUFFER to point to our data.
	pBuffer = &pb->NdisBuffer;
	NdisInitializeBuffer(pBuffer, pData, cbData);

	// Chain the NDIS_BUFFER to the start of the NDIS_PACKET
	NdisChainBufferAtBack(pPacket, pBuffer);
	NDIS_SET_PACKET_HEADER_SIZE(pPacket, sizeof(ETHERNET_MAC_HEADER));
	NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_SUCCESS);

#ifdef NDIS_BUS_DRIVER
	NDIS_PACKET *PacketArray[1];
	PacketArray[0]=pPacket;
	NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, 1);
#else
	// Perform the indicate on the timer thread because tying up the
	// SDIO receive indication thread can result in a deadlock.
	PLIST_ENTRY pEntry = (PLIST_ENTRY)(pPacket->MiniportReserved);
	Lock();
	InsertTailList(&m_RxPendingPacketList, pEntry);
	NdisSetEvent(&m_RxPendingEvent);
	Unlock();
#endif	

done:
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, "AR6K: -ReceiveWMIDataPacket");
}
Esempio n. 13
0
INT
	natpReceivePacketPassThrough(
		IN NDIS_HANDLE ProtocolBindingContext,
		IN PNDIS_PACKET Packet,
		IN FLT_PKT* pFltPkt
		)
{
	PFILTER_ADAPTER pAdapt =(PFILTER_ADAPTER)ProtocolBindingContext;
	NDIS_STATUS Status;
	PNDIS_PACKET MyPacket;
	BOOLEAN Remaining;
	PNDIS_BUFFER		pNewBuffer;

	if (NULL == pAdapt->MiniportHandle || pAdapt->natmDeviceState > NdisDeviceStateD0)
		return 0;
	NdisIMGetCurrentPacketStack(Packet, &Remaining);
	if (NULL == pFltPkt && Remaining){
		Status = NDIS_GET_PACKET_STATUS(Packet);
		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);

		return Status != NDIS_STATUS_RESOURCES ? 1 : 0;
    	}

	if(NULL == pFltPkt){

		NdisDprAllocatePacket(
			&Status,
			&MyPacket,
			pAdapt->RcvPP1
			);

		if (Status != NDIS_STATUS_SUCCESS){
			return 0;
		}

		*((PVOID*)&MyPacket->MiniportReserved) = Packet;

		MyPacket->Private.Head = Packet->Private.Head;
		MyPacket->Private.Tail = Packet->Private.Tail;

	}else{

		NdisDprAllocatePacket(
			&Status,
			&MyPacket,
			pAdapt->RcvPP2
			);

		if (Status != NDIS_STATUS_SUCCESS)
			return NDIS_STATUS_NOT_ACCEPTED;

		*((PVOID*)&MyPacket->MiniportReserved) = pFltPkt;

		NdisAllocateBuffer(
			&Status,
			&pNewBuffer,
			pAdapt->RcvBP,
			pFltPkt->pBuf,
			pFltPkt->uLen
			);

		if ( Status != NDIS_STATUS_SUCCESS ){

			NdisReinitializePacket (MyPacket);
			NdisFreePacket (MyPacket);

			return 0;
		}

		NdisChainBufferAtFront(MyPacket, pNewBuffer );
	}
	NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
	NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

	Status = NDIS_GET_PACKET_STATUS(Packet);

	NDIS_SET_PACKET_STATUS(MyPacket, Status);
	NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

	if (Status == NDIS_STATUS_RESOURCES){

		natpQueueReceivedPacket(pAdapt, MyPacket, TRUE);
	}else{

		natpQueueReceivedPacket(pAdapt, MyPacket, FALSE);
	}
	
	if (Status == NDIS_STATUS_RESOURCES)
	        NdisDprFreePacket(MyPacket);

	return Status != NDIS_STATUS_RESOURCES ? 1 : 0;
}
Esempio n. 14
0
VOID
NICIndicateReceivedPacket(
    IN PRCB             pRCB,
	IN ULONG            dataoffset,
    IN ULONG            BytesToIndicate,
	IN ULONG            PacketNum
    )
/*++

Routine Description:

    Initialize the packet to describe the received data and
    indicate to NDIS.
        
Arguments:

    pRCB - pointer to the RCB block    
    BytesToIndicate - number of bytes to indicate

Return value:

    VOID
--*/
{
    ULONG           PacketLength;
    PNDIS_BUFFER    CurrentBuffer = NULL;
    PETH_HEADER     pEthHeader = NULL;
    PMP_ADAPTER     Adapter = pRCB->Adapter;
    KIRQL           oldIrql;	
	PVOID  VirtualAddress=NULL;
	ASSERT(     PacketNum   <    RCB_BUFFERARRAY_SIZE);
	ASSERT((dataoffset+BytesToIndicate) <  pRCB->ulBufferSize);


    

	
    //NdisAdjustBufferLength(pRCB->Buffer, BytesToIndicate);
	//MmInitializeMdl(pRCB->BufferArray[PacketNum],pRCB->pDataForNTB+dataoffset,BytesToIndicate);
	VirtualAddress=MmGetMdlVirtualAddress(pRCB->BufferArray[PacketNum]);
	ASSERT(VirtualAddress!=NULL);
	NdisMoveMemory(VirtualAddress,pRCB->pDataForNTB+dataoffset,BytesToIndicate);
	NdisAdjustBufferLength(pRCB->BufferArray[PacketNum], BytesToIndicate);
	//NdisMoveMemory(pRCB->pDataForNet+NIC_BUFFER_SIZE*PacketNum,pRCB->pDataForNTB+dataoffset,BytesToIndicate);
    //
    // Prepare the recv packet
    //

    NdisReinitializePacket(pRCB->PacketArray[PacketNum]);

    *((PRCB *)pRCB->PacketArray[PacketNum]->MiniportReserved) = pRCB;

    //
    // Chain the TCB buffers to the packet
    //
    NdisChainBufferAtBack(pRCB->PacketArray[PacketNum], pRCB->BufferArray[PacketNum]);

    NdisQueryPacket(pRCB->PacketArray[PacketNum], NULL, NULL, &CurrentBuffer, (PUINT) &PacketLength);

    ASSERT(CurrentBuffer == pRCB->BufferArray[PacketNum]);

    pEthHeader = (PETH_HEADER)(pRCB->pDataForNTB+dataoffset);

    if(PacketLength >= sizeof(ETH_HEADER) && 
        Adapter->PacketFilter &&
        NICIsPacketAcceptable(Adapter, pEthHeader->DstAddr)){
            
        DEBUGP(MP_LOUD, ("Src Address = %02x-%02x-%02x-%02x-%02x-%02x", 
            pEthHeader->SrcAddr[0],
            pEthHeader->SrcAddr[1],
            pEthHeader->SrcAddr[2],
            pEthHeader->SrcAddr[3],
            pEthHeader->SrcAddr[4],
            pEthHeader->SrcAddr[5]));

        DEBUGP(MP_LOUD, ("  Dest Address = %02x-%02x-%02x-%02x-%02x-%02x\n", 
            pEthHeader->DstAddr[0],
            pEthHeader->DstAddr[1],
            pEthHeader->DstAddr[2],
            pEthHeader->DstAddr[3],
            pEthHeader->DstAddr[4],
            pEthHeader->DstAddr[5]));

        DEBUGP(MP_LOUD, ("Indicating packet = %p, Packet Length = %d\n", 
                            pRCB->PacketArray[PacketNum], PacketLength));

        NdisInterlockedIncrement(&pRCB->Ref);


        NDIS_SET_PACKET_STATUS(pRCB->PacketArray[PacketNum], NDIS_STATUS_SUCCESS);
        Adapter->nPacketsIndicated++;

        //
        // NDIS expects the indication to happen at DISPATCH_LEVEL if the
        // device is assinged any I/O resources in the IRP_MN_START_DEVICE_IRP.
        // Since this sample is flexible enough to be used as a standalone
        // virtual miniport talking to another device or part of a WDM stack for
        // devices consuming hw resources such as ISA, PCI, PCMCIA. I have to
        // do the following check. You should avoid raising the IRQL, if you
        // know for sure that your device wouldn't have any I/O resources. This
        // would be the case if your driver is talking to USB, 1394, etc.
        //
        if(Adapter->IsHardwareDevice){
            
            KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
            NdisMIndicateReceivePacket(Adapter->AdapterHandle,
                            &pRCB->PacketArray[PacketNum],
                            1);
            KeLowerIrql(oldIrql);            
            
        }else{
        
            NdisMIndicateReceivePacket(Adapter->AdapterHandle,
                            &pRCB->PacketArray[PacketNum],
                            1);
        }

    }else {
        DEBUGP(MP_VERY_LOUD, 
                ("Invalid packet or filter is not set packet = %p,Packet Length = %d\n",
                pRCB->PacketArray, PacketLength));        
    }            

}
INT
PtReceivePacket(
	IN	NDIS_HANDLE			ProtocolBindingContext,
	IN	PNDIS_PACKET		Packet
	)
/*++

Routine Description:

	ReceivePacket handler. Called by NDIS if the miniport below supports
	NDIS 4.0 style receives. Re-package the buffer chain in a new packet
	and indicate the new packet to protocols above us. Any context for
	packets indicated up must be kept in the MiniportReserved field.

	NDIS 5.1 - packet stacking - if there is sufficient "stack space" in
	the packet passed to us, we can use the same packet in a receive
	indication.

Arguments:

	ProtocolBindingContext - Pointer to our adapter structure.
	Packet - Pointer to the packet

Return Value:

	== 0 -> We are done with the packet
	!= 0 -> We will keep the packet and call NdisReturnPackets() this
			many times when done.
--*/
{
	PADAPT				pAdapt =(PADAPT)ProtocolBindingContext;
	NDIS_STATUS			Status;
	PNDIS_PACKET		MyPacket;
	BOOLEAN				Remaining;
	//------------------------------WestChamber---------------------------------
			BOOLEAN result=WestChamberReceiverMain(Packet,pAdapt);
			if(result==FALSE) {
				//Simply drop the packet.
				//return NDIS_STATUS_NOT_ACCEPTED;
				return 0;		//Thanks to Albert Jin.
			}
	//------------------------------WestChamber---------------------------------
	//
	// Drop the packet silently if the upper miniport edge isn't initialized
	//
	if (!pAdapt->MiniportHandle)
	{
		  return 0;
	}

#ifdef NDIS51
	//
	// Check if we can reuse the same packet for indicating up.
	// See also: PtReceive(). 
	//
	(VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);
	if (Remaining)
	{
		//
		// We can reuse "Packet". Indicate it up and be done with it.
		//
		Status = NDIS_GET_PACKET_STATUS(Packet);
		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);
		return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
	}
#endif // NDIS51

	//
	// Get a packet off the pool and indicate that up
	//
	NdisDprAllocatePacket(&Status,
						   &MyPacket,
						   pAdapt->RecvPacketPoolHandle);

	if (Status == NDIS_STATUS_SUCCESS)
	{
		PRECV_RSVD			RecvRsvd;

		RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
		RecvRsvd->OriginalPkt = Packet;

		MyPacket->Private.Head = Packet->Private.Head;
		MyPacket->Private.Tail = Packet->Private.Tail;

		//
		// Get the original packet (it could be the same packet as the one
		// received or a different one based on the number of layered miniports
		// below) and set it on the indicated packet so the OOB data is visible
		// correctly to protocols above us.
		//
		NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));

		//
		// Set Packet Flags
		//
		NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

		Status = NDIS_GET_PACKET_STATUS(Packet);

		NDIS_SET_PACKET_STATUS(MyPacket, Status);
		NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

		//
		// Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
		// NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
		// it might have changed! Use the value saved in the local variable.
		//
		if (Status == NDIS_STATUS_RESOURCES)
		{
			//
			// Our ReturnPackets handler will not be called for this packet.
			// We should reclaim it right here.
			//
			NdisDprFreePacket(MyPacket);
		}

		return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
	}
	else
	{
		//
		// We are out of packets. Silently drop it.
		//
		return(0);
	}
}
Esempio n. 16
0
/******************************************************************************
 *
 *  Name: HandleRxReadyEvent()
 *
 *  Description: Rx ready event handler
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value:        
 * 
 *  Notes:               
 *
 *****************************************************************************/
VOID
HandleRxReadyEvent(
    IN PMRVDRV_ADAPTER Adapter
)
{
    int           IsRxOK = 0;
    PRxPD         pRxPDCurrent;
    PNDIS_PACKET  pPacket;
    NDIS_STATUS   pStatus;


    DBGPRINT(DBG_RX | DBG_HELP,(L"+HandleRxReadyEvent()\n"));
    pRxPDCurrent = (PRxPD)(Adapter->pRxPD1);


//lykao, 060905, begin
    if (pRxPDCurrent->Status & MRVDRV_RXPD_STATUS_OK)
    {
        Adapter->RcvOK++;
        Adapter->DirectedFramesRcvOK++;
        wlan_compute_rssi(Adapter,pRxPDCurrent);
    }
    else
    {
        DBGPRINT(DBG_RX | DBG_WARNING,(L"WARNING: frame received with bad status\n"));

        //dralee++ 09212005 for error handling 
        pPacket = Adapter->pRxCurPkt;
        Adapter->pRxCurPkt = NULL; 
        if ( pPacket )
            ReturnRxPacketDesc(Adapter,pPacket);
        return;
    }
        
    pPacket = Adapter->pRxCurPkt;
    Adapter->pRxCurPkt = NULL;  

    if (Adapter->MediaConnectStatus == NdisMediaStateConnected)
    {              
        Adapter->ulRxByteInLastPeriod += Adapter->ulRxSize;  

        NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_SUCCESS);

        NdisMIndicateReceivePacket(Adapter->MrvDrvAdapterHdl, &pPacket, 1);
      
        pStatus = NDIS_GET_PACKET_STATUS(pPacket);
        
        if ((pStatus == NDIS_STATUS_RESOURCES) || (pStatus == NDIS_STATUS_SUCCESS))
        {
            // return packet
            DBGPRINT(DBG_RX|DBG_HELP, (L"Packet returned success or resources...\n"));
            ReturnRxPacketDesc(Adapter,pPacket);            
        }
        else
        {
            DBGPRINT(DBG_RX|DBG_ERROR, (L"Packet returned pending...\n"));
        }
    }
    else
    {
        ///pmkcache: bug#16956 ++		
        if (Adapter->bIsReconnectAssociation == TRUE)
        {
            Adapter->isPktPending = TRUE;
            if ( Adapter->pPendedRxPkt )
            {
                NKDbgPrintfW( L"ERROR, a pended RX packet has not been process!!\r\n" );
            }
            Adapter->pPendedRxPkt = pPacket;
            return;
        }
        ///pmkcache: bug#16956 --

        DBGPRINT(DBG_RX|DBG_ERROR, (L"Not connected, packet was dropped...\n"));
        ReturnRxPacketDesc(Adapter,pPacket);
    } 

    return;
}
NDIS_STATUS
PtReceive(
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  NDIS_HANDLE			MacReceiveContext,
	IN  PVOID				HeaderBuffer,
	IN  UINT				HeaderBufferSize,
	IN  PVOID				LookAheadBuffer,
	IN  UINT				LookAheadBufferSize,
	IN  UINT				PacketSize
	)
/*++

Routine Description:

	Handle receive data indicated up by the miniport below. We pass
	it along to the protocol above us.

	If the miniport below indicates packets, NDIS would more
	likely call us at our ReceivePacket handler. However we
	might be called here in certain situations even though
	the miniport below has indicated a receive packet, e.g.
	if the miniport had set packet status to NDIS_STATUS_RESOURCES.
		
Arguments:

	<see DDK ref page for ProtocolReceive>
Return Value:

	NDIS_STATUS_SUCCESS if we processed the receive successfully,
	NDIS_STATUS_XXX error code if we discarded it.

--*/
{
	PADAPT			pAdapt =(PADAPT)ProtocolBindingContext;
	PNDIS_PACKET	MyPacket, Packet;
	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;

	if (!pAdapt->MiniportHandle)
	{
		Status = NDIS_STATUS_FAILURE;
	}
	else do
	{
		//
		// Get at the packet, if any, indicated up by the miniport below.
		//
		Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
		if (Packet != NULL)
		{
			//------------------------------WestChamber---------------------------------
			BOOLEAN result=WestChamberReceiverMain(Packet,pAdapt);
			if(result==FALSE) {
				//Simply drop the packet.
				return NDIS_STATUS_NOT_ACCEPTED;
			}
			//------------------------------WestChamber---------------------------------
		    //
		    // The miniport below did indicate up a packet. Use information
		    // from that packet to construct a new packet to indicate up.
		    //

#ifdef NDIS51
			//
			// NDIS 5.1 NOTE: Do not reuse the original packet in indicating
			// up a receive, even if there is sufficient packet stack space.
			// If we had to do so, we would have had to overwrite the
			// status field in the original packet to NDIS_STATUS_RESOURCES,
			// and it is not allowed for protocols to overwrite this field
			// in received packets.
			//
#endif // NDIS51

			//
			// Get a packet off the pool and indicate that up
			//
			NdisDprAllocatePacket(&Status,
			   						  &MyPacket,
			   						  pAdapt->RecvPacketPoolHandle);

			if (Status == NDIS_STATUS_SUCCESS)
			{
				//
				// Make our packet point to data from the original
				// packet. NOTE: this works only because we are
				// indicating a receive directly from the context of
				// our receive indication. If we need to queue this
				// packet and indicate it from another thread context,
				// we will also have to allocate a new buffer and copy
				// over the packet contents, OOB data and per-packet
				// information. This is because the packet data
				// is available only for the duration of this
				// receive indication call.
				//
				MyPacket->Private.Head = Packet->Private.Head;
				MyPacket->Private.Tail = Packet->Private.Tail;

				//
				// Get the original packet (it could be the same packet as the
				// one received or a different one based on the number of layered
				// miniports below) and set it on the indicated packet so the OOB
				// data is visible correctly at protocols above.
				//
				NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
				NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

				//
				// Copy packet flags.
				//
				NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

				//
				// Force protocols above to make a copy if they want to hang
				// on to data in this packet. This is because we are in our
				// Receive handler (not ReceivePacket) and we can't return a
				// ref count from here.
				//
				NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);

				//
				// By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim
				// this packet as soon as the call to NdisMIndicateReceivePacket
				// returns.
				//

				NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

				//
				// Reclaim the indicated packet. Since we had set its status
				// to NDIS_STATUS_RESOURCES, we are guaranteed that protocols
				// above are done with it.
				//
				NdisDprFreePacket(MyPacket);

				break;
			}
		}
		else
		{
			//
			// The miniport below us uses the old-style (not packet)
			// receive indication. Fall through.
			//
		}

		//
		// Fall through if the miniport below us has either not
		// indicated a packet or we could not allocate one
		//
		pAdapt->IndicateRcvComplete = TRUE;
		switch (pAdapt->Medium)
		{
		  case NdisMedium802_3:
		  case NdisMediumWan:
			 NdisMEthIndicateReceive(pAdapt->MiniportHandle,
											 MacReceiveContext,
											 HeaderBuffer,
											 HeaderBufferSize,
											 LookAheadBuffer,
											 LookAheadBufferSize,
											 PacketSize);
			 break;

		  case NdisMedium802_5:
			 NdisMTrIndicateReceive(pAdapt->MiniportHandle,
											MacReceiveContext,
											HeaderBuffer,
											HeaderBufferSize,
											LookAheadBuffer,
											LookAheadBufferSize,
											PacketSize);
			 break;

		  case NdisMediumFddi:
			  /*
			 NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
											  MacReceiveContext,
											  HeaderBuffer,
											  HeaderBufferSize,
											  LookAheadBuffer,
											  LookAheadBufferSize,
											  PacketSize);
											  */
			 break;

		  default:
			 ASSERT(FALSE);
			 break;
		}

	} while(FALSE);

	return Status;
}