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 + -
显示快捷键?