halether.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 848 行 · 第 1/2 页

C
848
字号


/////////////////////////////////////////////////////////////////////////////////
//	OEMEthGetFrame
//
//	Check to see if a frame has been received, and if so copy to buffer. An optimization
//  which may be performed in the Ethernet driver is to filter out all received broadcast
//	packets except for ARPs.  This is done in the NE2000 driver.
//
//	Return Value:
//	Return TRUE if frame has been received, FALSE if not.
//
BOOL
OEMEthGetFrame(
    BYTE *pData,       // OUT - Receives frame data
    UINT16 *pwLength)  // IN  - Length of Rx buffer
                       // OUT - Number of bytes received
{
    BOOL    bStatus;

#ifdef IMGSHAREETH
    BOOL    bTaken;     
	
    ProcessVMiniSend();

    while (1)
    {        
        
	if (bDecChip)
	    bStatus = NIC_FTbl->NIC_OtherGetFrame(pData, pwLength);
	else
	    bStatus = NIC_FTbl->NIC_GetFrame(pData, pwLength);

        if (bStatus)
        {
            VBridgeKIndicateOneRxBuffer(pData, *pwLength, FALSE, &bTaken);
	    if (!bTaken)              
                return bStatus;            
        }
        else
            break;
    }
    return (FALSE);
#else

    if (bDecChip)
        bStatus = NIC_FTbl->NIC_OtherGetFrame(pData, pwLength);
    else
        bStatus = NIC_FTbl->NIC_GetFrame(pData, pwLength);
	
    return bStatus;

#endif	// IMGSHAREETH.

}



/////////////////////////////////////////////////////////////////////////////////
// OEMEthSendFrame
//
//  Send Ethernet frame.  
//
//  Return Value:
//   TRUE if frame successfully sent, FALSE otherwise.
//
BOOL
OEMEthSendFrame(
    BYTE *pData,     // IN - Data buffer
    DWORD dwLength)  // IN - Length of buffer
{
    int retries = 0;		
	

	// EdbgOutputDebugString ("<                Send 0x%x = %d\r\n", pData, dwLength);

    // Let's be persistant here
    while (retries++ < 4) {	
        if (!NIC_FTbl->NIC_SendFrame(pData, dwLength))
		{
			//EdbgOutputDebugString ("+/-OEMEthSendFrame() return TRUE\r\n");			
#ifdef IMGSHAREETH
            ProcessVMiniSend();
#endif	// IMGSHAREETH.
            return TRUE;
		}
        else
			;
            //EdbgOutputDebugString("!OEMEthSendFrame failure, retry %u\n",retries);
    }		
	//EdbgOutputDebugString ("+/-OEMEthSendFrame() return FALSE\r\n");
    return FALSE;
}


#ifdef IMGSHAREETH

//
//	These functions are only needed if vmini is in.
//	i.e. if IMGSHAREETH is set.
//


////////////////////////////////////////////////////////////////////////////////
//	OEMEthSetFilter()
//
//	Description:
//		
//		This function is used by VMINI to inform the underlying ethernet
//		library on the filtering mode it requires.
//
//	Arguments:
//
//		pdwRequestedFilter	:: The requested filter.
//							   Identical constants have been added in 
//							   that mimics NDIS_PACKET_TYPE_XXX constants.
//
//	Return Value:
//
//		TRUE	:: if we can set the filter.
//		FALSE	:: otherwise..
//
//
//	Note:
//		
//		As a minimum to get vmini to work, we need to support
//		PACKET_TYPE_DIRECTED 
//		PACKET_TYPE_BROADCAST
//
//	
BOOL
OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter)
{

	if (pfnCurrentPacketFilter)
	{
		//EdbgOutputDebugString(
			//"OEMEthCurrentPacketFilter set to [0x%x]\r\n",
			//*pdwRequestedFilter);	

		//
		//	Note that we can't do it immediately here, since we are called 
		//	by user mode code.
		//	So what we do is to set the flag here for the kernel mode code
		//	to pick up.
		//

		dwFilter   = *pdwRequestedFilter;
		bNewFilter = TRUE;
		return TRUE;
	}
	else
	{
		//
		//	Oh well, eth driver does not yet support filter setting
		//	So if it is PACKET_TYPE_DIRECTED, PACKET_TYPE_MULTICAST, 
		//	PACKET_TYPE_BROADCAST, we just lie that we are ok with it.
		//	Since EDBG will run in this mode anyway..
		//

		DWORD	dwInherentlySupported = 
					PACKET_TYPE_MULTICAST	| 
					PACKET_TYPE_DIRECTED	| 
					PACKET_TYPE_BROADCAST;

		if (*pdwRequestedFilter == dwInherentlySupported)
			return TRUE;
		else
			return FALSE;
	}

}	//	OEMEthCurrentPacketFilter()



////////////////////////////////////////////////////////////////////////////////
//	OEMEthMulticastList()
//
//	Description:
//
//		This function is used by VMINI to inform the underlying ethernet 
//		library on multicast addresses that winsock app is interested in.
//		
//	Arguments:
//
//		pucMulticastAddressList	:: Pointer to an array of multicast addresses.
//		dwNoOfAddresses			:: Number of addresses passed in to us.
//
//	Return Value:
//		
//		TRUE	::  if we can set the underlying edbg ethernet libary to start
//						filtering on these multicast addresses.
//
//		FALSE	::  otherwise.
//
BOOL
OEMEthMulticastList(PUCHAR	pucMulticastAddressList, DWORD	dwNoOfAddresses)
{
	//
	//	This platform does not support multicast yet..
	//

	DWORD	i;
	BOOL	bReturnValue;

	//EdbgOutputDebugString(
		//"OEMEthMulticastList():: No of Entries [%d]\r\n",
			//dwNoOfAddresses);	

	for (i = 0 ; i < dwNoOfAddresses ; i++)
	{
		//EdbgOutputDebugString(
			//"[%d] : %x - %x - %x - %x - %x - %x\r\n",
			//i,
			//pucMulticastAddressList[6*i+0],
			//pucMulticastAddressList[6*i+1],
			//pucMulticastAddressList[6*i+2],
			//pucMulticastAddressList[6*i+3],
			//pucMulticastAddressList[6*i+4],
			//pucMulticastAddressList[6*i+5]);
	}

	if (pfnMulticastList)
		bReturnValue = pfnMulticastList(pucMulticastAddressList, dwNoOfAddresses);
	else
		bReturnValue = FALSE;

	//EdbgOutputDebugString(
		//"OEMEthMulticastList returning [%d]\r\n",
		//bReturnValue);


	return bReturnValue;
	

}	//	OEMEthMulticastList()

#endif  // IMGSHAREETH


/////////////////////////////////////////////////////////////////////////////////
//	OEMEthQueryClientInfo
//
//		Return address information for default ethernet services, plus a buffer pool to use
//		for formatting and receiving EDBG packets (single buffer pool specified, divided in
//		two for Rx and Tx buffers).  By specifying a smaller window size, less memory can be
//		used (but the protocol will be less efficient...).  The amount of memory required per
//		client is (2*WindowSize*1500) bytes.
//
//		For Odo, we reserve 3 buffer pools worth of memory in the bib file, based on the IMGEBOOT
//		flag being set.
//
//		Return Value:
//		If client can be configured, return TRUE and fill in addressing and buffer info. Otherwise
//		return FALSE.  For Odo, configure clients based on the flags set by Eshell (received in the
//		JUMPIMG command by eboot, and placed in the uninitalized driver globals section).
//
BOOL
OEMEthQueryClientInfo(
    UCHAR Service,         // IN - Service ID (one of EDBG_SVC defs from ethdbg.h).
    EDBG_ADDR *pPeerAddr,  // OUT -Filled in with the peer Ether/IP address and UDP port number.
    PUCHAR  pWindowSize,   // OUT -Filled in with the client window size.
    PUCHAR *ppBufferPool)  // OUT -Filled in with the packet buffer pool address.
{
    
	//EdbgOutputDebugString ("[st] *pWindowSize = 0x%x - %d \r\n", EDBG_WINDOW_SIZE, EDBG_WINDOW_SIZE);
	//EdbgOutputDebugString ("[st] EDBG_PHYSICAL_MEMORY_START = 0x%x \r\n", EDBG_PHYSICAL_MEMORY_START);
	//EdbgOutputDebugString ("[st] EDBG_DFLT_BUFFER_POOL_SIZE = 0x%x - %d\r\n", EDBG_DFLT_BUFFER_POOL_SIZE, EDBG_DFLT_BUFFER_POOL_SIZE);
	

    // We use the default window size (8) for all services
    *pWindowSize = EDBG_WINDOW_SIZE;
    
    switch (Service)
    {
        // Check the flag in driver globals (set by eboot when it receives the JUMPIMG command)
        case EDBG_SVC_DBGMSG:
            if (! (pDriverGlobals->etherFlags & EDBG_FL_DBGMSG)) {
                return FALSE;
            }
            memcpy(pPeerAddr, &pDriverGlobals->DbgHostAddr,sizeof(EDBG_ADDR));
            *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START;
			
			//EdbgOutputDebugString ("[st] EDBG_SVC_DBGMSG returning: 0x%x \r\n", *ppBufferPool);
			//EdbgOutputDebugString ("[st] pPeerAddr.dwIP = %s\r\n", inet_ntoa(pPeerAddr->dwIP));
            break;

        case EDBG_SVC_PPSH:
            if (! (pDriverGlobals->etherFlags & EDBG_FL_PPSH)) {
                return FALSE;
            }
            memcpy(pPeerAddr, &pDriverGlobals->PpshHostAddr,sizeof(EDBG_ADDR));
            *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START + EDBG_DFLT_BUFFER_POOL_SIZE;

			//EdbgOutputDebugString ("[st] EDBG_SVC_PPSH returning: 0x%x \r\n", *ppBufferPool);
			//EdbgOutputDebugString ("[st] pPeerAddr.dwIP = %s\r\n", inet_ntoa(pPeerAddr->dwIP));
            break;


        case EDBG_SVC_KDBG:
            if (! (pDriverGlobals->etherFlags & EDBG_FL_KDBG)) {
                return FALSE;
            }
            memcpy(pPeerAddr, &pDriverGlobals->KdbgHostAddr,sizeof(EDBG_ADDR));    
            *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START + 2*EDBG_DFLT_BUFFER_POOL_SIZE;

			//EdbgOutputDebugString ("[st] EDBG_SVC_KDBG returning: 0x%x \r\n", *ppBufferPool);
			//EdbgOutputDebugString ("[st] pPeerAddr.dwIP = %s\r\n", inet_ntoa(pPeerAddr->dwIP));
            break;            
        default:
            return FALSE;
    }
    return TRUE;
}


/////////////////////////////////////////////////////////////////////////////////
//	This function is used when Kernel's KFileTimeToSystemTime is not yet 
//	available...
//
BOOL 
ether_KFileTimeToSystemTime(
    const FILETIME *lpft, 
    LPSYSTEMTIME lpst
    )
{
    DWORD dwBase;
	ULONG Minutes;
	ULONG Seconds;

	// EdbgOutputDebugString ("+/- ether_KFileTimeToSystemTime()\r\n");

    //
    // Take 32-bits of the 64 that we care about. New counter rate is 78125/sec.
    //    
	dwBase = ((lpft->dwHighDateTime << 25) & 0xFE000000) |
             ((lpft->dwLowDateTime  >>  7) & 0x01FFFFFF);

	Seconds = dwBase / 78125;
    lpst->wSecond = (WORD)(Seconds % 60);
    
    Minutes = Seconds / 60;
    lpst->wMinute = (WORD)(Minutes % 60);
    
    lpst->wHour = (WORD)(Minutes / 60);
    
    //
    // Okay to wrap on day. Don't care about milliseconds.
    //
    lpst->wMilliseconds = 0;
    lpst->wYear = 1998;
    lpst->wMonth = 1;
    lpst->wDay = 1;

    return(TRUE);
}



/////////////////////////////////////////////////////////////////////////////////
// OEMEthGetSecs
//
//  Return a count of seconds from some arbitrary time (the absolute value is not important,
//  so long as it increments appropriately).
//

DWORD OEMEthGetSecs( void ) {
 
	/////////////////////////////////////////////////////////////////////////////
	//	BIG NOTE HERE:
	//	For some reason, KFileTimeToSystemTime() will fail downloading in PPFS
	//	"S" command.
	//	Likelyhood that it overshoots the stack that causes double exception.
	//	Since the caller (NE2000) requires resolution only in second, 
	//	we can simply return Current MSec counter dividec by 1000.
	//	That solves the double exceptions in "S" command and other symptoms like:
	//	-	Windbg ether not working.
	//	-	Upload is super slow.
#define pVRC5074 ((PVRC5074_CONTROL)(VRC5074_BASE | KSEG1_BASE))
    return ((DWORD)((0xFFFFFFFF - pVRC5074->T2CNTR.Lo)/10));


/*	--------------------------- not using this -----------------------------------
	BOOL fInitialized;
    SYSTEMTIME st;

    if (KFileTimeToSystemTime == NULL) 
	{
        //
        // This function isn't mapped and OEMGetRealTime might need it. We only
        // care about incrementing seconds so point to our trimmed implementation.
        // We don't really need to worry about protecting this read/set because
        // during the time that the function pointer is null, we aren't 
        // scheduling so we are okay to read and set blindly.        
		//
		
		OEMWriteDebugString (TEXT("EEEE1\r\n"));
        fInitialized = FALSE;
        KFileTimeToSystemTime = ether_KFileTimeToSystemTime;		

    } else 			
        fInitialized = TRUE;
		
    OEMGetRealTime( &st );	
	
    if (!fInitialized) 
	{
		// Put it back the way we found it.
        //
        KFileTimeToSystemTime = NULL;
    }	
	
    return ((60UL * (60UL * (24UL * (31UL * st.wMonth + st.wDay) + st.wHour) + st.wMinute)) + st.wSecond);
	-----------------------------------------------------------------------------
*/


}


#endif	// MIPS


⌨️ 快捷键说明

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