⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rndis.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 4 页
字号:

		CELOGMSG (ZONE_MEM,
			(TEXT("%%> RcvRndisPacket[0x%x] alloced.\r\n"),
			pRcvRndisPacket));

		memset(
			pRcvRndisPacket,
			0x00,
			sizeof(RCV_RNDIS_PACKET));

		CELOGMSG (0, 
			(TEXT("Initially: pRcvRndisPacket->dwReturnsPending == [%d]\r\n"),
			pRcvRndisPacket->dwReturnsPending));
		

		pRcvRndisPacket->pDataWrapper = pDataWrapper;

		//
        //  Prepare NDIS packets for indicating up. 
        //
		
		do
		{
			pRndisPacket = RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(pRndisMessage);

			//
            // Some sanity checks.
            //
            
			if (pRndisMessage->MessageLength > dwLengthRemaining)
            {
				CELOGMSG (ZONE_ERROR,
					(TEXT("RNdis:: Invalid RndisPacket l[%d] rem [%d]\r\n"),
					pRndisMessage->MessageLength,
					dwLengthRemaining));         
                
				break;
            }

            if (pRndisPacket->DataLength > pRndisMessage->MessageLength)
            {
				CELOGMSG (ZONE_ERROR,
					(TEXT("RNdis:: Err! RndisPacket l[%d]>MsgLen[%d]\r\n"),
					pRndisPacket->DataLength,
					pRndisMessage->MessageLength));
                
				break;
            }

            //
            //	Allocate an NDIS packet to do the indication with.            
			//	

            NdisAllocatePacket(
				&NdisStatus, 
				&pNdisPacket, 
				NdisPacketPool);


			if (NdisStatus != NDIS_STATUS_SUCCESS)
            {
                pNdisPacket = NULL;

				CELOGMSG (ZONE_ERROR,
					(TEXT("RNdis:: Err! no mem for NDIS_PACKET...\r\n")));		
                
                break;
            }


			//
			//	Protocol driver can keep the packet and return later..
			//

			NDIS_SET_PACKET_HEADER_SIZE(pNdisPacket, 14);
			NDIS_SET_PACKET_STATUS(pNdisPacket, NDIS_STATUS_SUCCESS);
			NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(
				pNdisPacket, NULL, 0);


			//
			//	Here is the NDIS_BUFFER wrapper.
			//

			NdisAllocateBuffer(
				&NdisStatus,
                &pNdisBuffer,
				NdisBufferPool,
				GET_PTR_TO_RNDIS_DATA_BUFF(pRndisPacket),
				pRndisPacket->DataLength);

			if (NdisStatus != NDIS_STATUS_SUCCESS)
            {
				CELOGMSG (ZONE_ERROR, 
					(TEXT("RNdis:: Err! non mem for NDIS_BUFFER..\r\n")));			
                
                NdisFreePacket(pNdisPacket);                
                break;
            }


			//
			//	Cool, by here we have NDIS_PACKET and NDIS_BUFFER..
			//	Link them and queue them in PacketArray.
			//

			NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

			#if 0
				CELOGMSG (ZONE_RNDIS, (TEXT("RX packet [%d] bytes: \r\n"),
					pNdisBuffer->BufferLength));
				DumpMemory(
					pNdisBuffer->VirtualAddress,
					MIN(48, pNdisBuffer->BufferLength));
			#endif

			CELOGMSG (0, (TEXT(">> [%d] bytes.\r\n"),
				pNdisBuffer->BufferLength));

			PacketArray[dwNumberOfPackets] = pNdisPacket;
            dwNumberOfPackets++;		

			*(RESERVED_FROM_RECV_PACKET(pNdisPacket)) = pRcvRndisPacket;

			//
			//	Next packet please..
			//

			dwLengthRemaining -= pRndisMessage->MessageLength;            
			pRndisMessage     = 
				(PRNDIS_MESSAGE)((ULONG_PTR)pRndisMessage +
								  pRndisMessage->MessageLength);

			NdisInterlockedIncrement(
				&pRcvRndisPacket->dwReturnsPending);

			CELOGMSG (0, 
				(TEXT("pRcvRndisPacket->dwReturnsPending == [%d]\r\n"),
				pRcvRndisPacket->dwReturnsPending));



			//
			//	See if we have reached the maximum, or there is no packet
			//	left in the RNDIS_PACKET message.
			//	We should have told RNDIS host the max ndis packet it may
			//	include in one RNDIS_MESSAGE.   So if it goes beyond that
			//	we toss 'em..
			//

			if ((dwNumberOfPackets == RNDIS_MAX_PACKETS_PER_MESSAGE) ||
                (dwLengthRemaining <  RNDIS_MESSAGE_SIZE(RNDIS_PACKET)))
            {
				ASSERT(dwNumberOfPackets < RNDIS_MAX_PACKETS_PER_MESSAGE);
				break;
			}
		}	
		while (dwLengthRemaining >= RNDIS_MESSAGE_SIZE(RNDIS_PACKET));


		//
		//	Indicate to VMINI which will pass it to CE stack.
		//	Each packet will then come back via RndisReturnIndicatedPacket()
		//	when the dwReturnsPending == 0 we then release the
		//	pRcvRndisPacket and return the PDATA_WRAPPER to PDD.
		//

		if (dwNumberOfPackets)
		{
			ASSERT(pRcvRndisPacket->dwReturnsPending == dwNumberOfPackets);

			CELOGMSG (ZONE_RNDIS, 
				(TEXT("IND to RNDISMINI1 [0x%x]: DataWrap[0x%x]-[%d]pkts.\r\n"),
				pRcvRndisPacket,
				pRcvRndisPacket->pDataWrapper,
				dwNumberOfPackets));

			VMiniIndicatePackets(
				PacketArray,
				dwNumberOfPackets);		

			RndisMdd.dwTransmitOkay += dwNumberOfPackets;		

			//
			//	CE VMINI will call RndisReturnIndicatedPacket() to return 
			//	 this packet.
			//

			bReturnImmediately = FALSE;
		}

	} 
	while (FALSE);

	//
	//	If we don't need to retain this packet, return to PDD immediately..
	//
		
	if (bReturnImmediately)
	{		
		//
		//	indicate this packet is returned immediately..
		//
		
		RndisMdd.PddCharacteristics.IndicateRndisPacketCompleteHandler(
			pDataWrapper);	

		if (pRcvRndisPacket)
		{
			FREE_RCV_RNDIS_PACKET(pRcvRndisPacket);
			CELOGMSG (ZONE_MEM,
				(TEXT("%%> RcvRndisPacket[0x%x] freed.\r\n"),
				pRcvRndisPacket));
		}
	}			
*/
}	//	RndisProcessPacket()



////////////////////////////////////////////////////////////////////////////////
//	RndisReturnIndicatedPacket()
//	
//	Routine Description:
//
//		Handle packet return sent to VMini earlier..  
//	
//	Arguments:
//
//		pNdisPacket	:: The packet we indicate to VMini in 
//					   VMiniIndicatePackets().
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise.
//
/*
void
RndisReturnIndicatedPacket(
	PNDIS_PACKET	pNdisPacket)
{
	PRCV_RNDIS_PACKET	pRcvRndisPacket;
	DWORD				dwReturnsPending;
	PNDIS_BUFFER		pNdisBuffer;

	pRcvRndisPacket  = *(RESERVED_FROM_RECV_PACKET(pNdisPacket));
	dwReturnsPending = NdisInterlockedDecrement(
							&pRcvRndisPacket->dwReturnsPending);

	CELOGMSG (ZONE_RNDIS, 
		(TEXT("RNDISMINI1 Returns[0x%x] : Wrap[0x%x] Pend[%d]\r\n"),
		pRcvRndisPacket,
		pRcvRndisPacket->pDataWrapper,
		dwReturnsPending));

	NdisQueryPacket(
		pNdisPacket,
        NULL,
        NULL,
        &pNdisBuffer,
        NULL);

	NdisFreePacket(pNdisPacket);
	NdisFreeBuffer(pNdisBuffer);

	if (dwReturnsPending == 0)
	{
		//
		//	All NDIS_PACKETs consumed, we can now return the PDATA_WRAPPER
		//	passed to us in RndisProcessPacket() and then release the 
		//	RCV_RNDIS_PACKET wrapper.
		//

		CELOGMSG (0, 
			(TEXT("RNdis:: VMini consumed RNDIS_PACKET[0x%x]..\r\n"),
			pRcvRndisPacket));

		RndisMdd.PddCharacteristics.IndicateRndisPacketCompleteHandler(
			pRcvRndisPacket->pDataWrapper);
		
		FREE_RCV_RNDIS_PACKET (pRcvRndisPacket);

		CELOGMSG (ZONE_MEM,
			(TEXT("%%> RcvRndisPacket[0x%x] freed.\r\n"),
			pRcvRndisPacket));
	}

}	//	RndisReturnIndicatedPacket()

*/



LPVOID
NKCreateStaticMapping(
    DWORD dwPhysBase,
    DWORD dwSize
    ) ;




////////////////////////////////////////////////////////////////////////////////
//	RndisInit()
//	
//	Routine Description:
//
//		Our one and only chance to init..
//	
//	Arguments:
//
//		None.
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise.
//

BOOL RndisInit( BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3])
{
	DWORD dwWaitMSec;
#define INITIALTIME_SEC 100
//	NDIS_STATUS		Status;
	DWORD dwSysInt=0;
	EdbgOutputDebugString("Rndis:: initialization: with addr=%x\r\n",pbBaseAddress);
	if (pbBaseAddress ) { // Open the following 
		pbBaseAddress=
			(PBYTE)NKCreateStaticMapping((DWORD)pbBaseAddress>>8,0x100000L);
		EdbgOutputDebugString("Rndis:: Address static map to addr=%x\r\n",pbBaseAddress);
	};
	memset(&RndisMdd,0,sizeof(RndisMdd));
	RndisMdd.bPddSending = FALSE;
	EdbgOutputDebugString("Rndis:: initialization!\r\n");

// Initialize The Buffer
	InitBuffer(&MsgBufferDesc, MsgBuffer , MAX_PACKET_SIZE+4*(sizeof(DATA_WRAPPER)+sizeof(DWORD)));
// Initialize The Ethnet Frame Buffer
	InitBuffer(&EthBufferDesc, EthBuffer , (MAX_ETH_BLOCK+sizeof(DWORD))*10);

	if (PDDInit(&(RndisMdd.PddCharacteristics), pbBaseAddress)) {
		DWORD dwStartSec;
        ULONG ulRequiredLength=0;
		EdbgOutputDebugString("Rndis:: PDDInit Success!\r\n");
		RndisMdd.dwDeviceState = RNDIS_UNINITIALIZED;
        if (pbBaseAddress==NULL) { // First Time initialize.
            if (!RndisMdd.PddCharacteristics.GetHandler(
                REQ_ID_DEVICE_MACADDR,
                MacAddr,
                6,
                &ulRequiredLength))
            {
                EdbgOutputDebugString("Rndis:: Err no MAC address read from PDD.\r\n");
                return FALSE;
            }
        }
        memcpy(RndisMdd.PermanentNwAddr,MacAddr,6);
        RndisMdd.PermanentNwAddr[0] |= 0x02;
        EdbgOutputDebugString("Rndis:: Get MAC address %x,%x,%x\r\n",MacAddr[0],MacAddr[1],MacAddr[2]);
		dwStartSec=OEMEthGetSecs();
		while (OEMEthGetSecs()-dwStartSec<=INITIALTIME_SEC) {
//			PDD_ISR();
			RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
			if (RndisMdd.dwDeviceState == RNDIS_INITIALIZED) {
				break;
			}

		}
	}
	if (RndisMdd.dwDeviceState == RNDIS_INITIALIZED) {
		DWORD dwStartSec=OEMEthGetSecs();
		EdbgOutputDebugString("Rndis:: initialization: Success\r\n");
		while (OEMEthGetSecs()-dwStartSec<=5) {
			PVOID pDataBuffer=NULL;
			WORD  wLength;
			RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
			// Dump Any data we recevied.
			if (GetFirstUsedBuffer(&EthBufferDesc,&pDataBuffer, &wLength)==TRUE && pDataBuffer!=NULL) {
				FreeBuffer(&EthBufferDesc,pDataBuffer);
			};
		};
		return TRUE;
	}
	else {
		EdbgOutputDebugString("Rndis:: initialization: Fail!\r\n");
		return FALSE;
	};
}	//	RndisInit()

DWORD RndisGetIrq() {
		// Ugly, We do not have any other way to return IRQ.
	return RndisMdd.PddCharacteristics.dwIRQ;
};
void RndisGetPCICard(PDWORD pdwBaseAddr, PBYTE pucIrq)
{
	*pdwBaseAddr=RndisMdd.PddCharacteristics.dwBaseAddr;
	*pucIrq=(BYTE)RndisMdd.PddCharacteristics.dwIRQ;
}
////////////////////////////////////////////////////////////////////////////////
//	RndisDeInit()
//	
//	Routine Description:
//
//		Reverse what's done in RndisInit()
//	
//	Arguments:
//
//		None.
//
//	Return Value:
//
//		None.
//
void
RndisDeInit(void)
{
/*
	NdisFreePacketPool(NdisPacketPool);
	NdisFreeBufferPool(NdisBufferPool);
	SetEvent(g_TxEvent);	

	ExDeleteNPagedLookasideList(&RcvRndisPacketLookAsideList);
*/
}	//	RndisDeInit()

void
RndisCurrentPacketFilter(DWORD	dwFilter)
{
	// Do know how.
}


BOOL
RndisMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
	return TRUE;
}
DWORD 
RndisGetPendingInts(void)
{
	DWORD dwWaitMSec;
    //EdbgOutputDebugString("+NE2000GetPendingInts\r\n");
//	PDD_ISR();
	RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
    //EdbgOutputDebugString("-NE2000GetPendingInts\r\n");
	if (GetFirstUsedBuffer(&EthBufferDesc,NULL,NULL)) {
#ifdef DEBUG_SINGLE_CHAR
        EdbgOutputDebugString("R"); // indicating a received packet
#endif
        return INTR_TYPE_RX;    
    }
#ifdef DEBUG_SINGLE_CHAR
    EdbgOutputDebugString("B"); // discarding non-ARP broadcast traffic.
#endif
    return 0;    
}   // NE2000GetPendingInts
void RndisEnableInts (void )
{
	RndisMdd.PddCharacteristics.SetHandler(REQ_ID_ENABLE_INT,NULL,0);

};
void RndisDisableInts (void)
{
	RndisMdd.PddCharacteristics.SetHandler(REQ_ID_DISABLE_INT,NULL,0);

};


DWORD  RndisSetOptions(DWORD dwOptions)
{
	return dwOptions;

}


void MddInitializeCriticalSection(CRITICAL_SECTION *pCS) {;};
void MddDeleteCriticalSection(CRITICAL_SECTION *pCS){;};
void MddEnterCriticalSection(CRITICAL_SECTION *pCS){;};
void MddLeaveCriticalSection(CRITICAL_SECTION *pCS){;};

void RndisMiniCeLogMsg (LPCTSTR szFormat,... )
{
/*	TCHAR szBuffer[1024];
	va_list pArgs; 
	va_start(pArgs, szFormat);
	_vsntprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), szFormat, pArgs);
	va_end(pArgs);
	CeLogData(TRUE,CELID_RAW_WCHAR,szBuffer,(WORD)((_tcslen(szBuffer)+1)*sizeof(TCHAR)),
		CELZONE_ALWAYSON, 0, 0, FALSE);
*/
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -