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

📄 halether.c

📁 RTL8139 网卡驱动源码 for WinCE.net CEPC
💻 C
📖 第 1 页 / 共 2 页
字号:
 *
 * Return Value:
 *    Return bitmask indicating which interrupts are pending.  Currently, the ones
 *    that EDBG cares about are the following (others should be handled internally):
 *       INTR_TYPE_RX   -- Receive interrupt. IST will call into GetFrame to read data.
 */
DWORD
OEMEthISR()
{
#ifdef IMGSHAREETH
    ProcessVMiniSend();
#endif

    return (pfnEDbgGetPendingInts());    
}

/* 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 both the SMC9000 and NE2000 drivers.
 *
 * 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
{
#ifdef IMGSHAREETH
    BOOL    bStatus;
    BOOL    bTaken;
    UINT16  wOriginalLength;

    ProcessVMiniSend();

    //
    //  ne2000 ether library has a minor problem of returning incorrect
    //  Ethernet packet size if we give it buffer > max Ether MTU.
    //  So, pass in only ether MTU if the incoming buffer is greater
    //  than ether MTU.
    //

    if (*pwLength >= 1514)
        wOriginalLength = 1514;
    else
        wOriginalLength = *pwLength;
    
    while (1)
    {   
        *pwLength = wOriginalLength;

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

    return (FALSE);
#else
    return (pfnEDbgGetFrame(pData, pwLength));

#endif
    
}

/* 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;
    while ( retries++ < 4 ) {
        if ( !pfnEDbgSendFrame(pData, dwLength) )
        {

#ifdef IMGSHAREETH
            ProcessVMiniSend();
#endif
            return (TRUE);
        }
        else
            EdbgOutputDebugString("!OEMEthSendFrame failure, retry %u\n",retries);
    }
    return (FALSE);
}

/* 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.
 *
 *  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.
{

    // 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 ( ! (pBootArgs->ucEshellFlags & EDBG_FL_DBGMSG) ) {
            return (FALSE);
        }
        memcpy(pPeerAddr, &pBootArgs->DbgHostAddr,sizeof(EDBG_ADDR));
        *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START;
        break;
    case EDBG_SVC_PPSH:
        if ( ! (pBootArgs->ucEshellFlags & EDBG_FL_PPSH) ) {
            return (FALSE);
        }
        memcpy(pPeerAddr, &pBootArgs->CeshHostAddr,sizeof(EDBG_ADDR));
        *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START + EDBG_DFLT_BUFFER_POOL_SIZE;
        break;
    case EDBG_SVC_KDBG:
        if ( ! (pBootArgs->ucEshellFlags & EDBG_FL_KDBG) ) {
            return (FALSE);
        }
        memcpy(pPeerAddr, &pBootArgs->KdbgHostAddr,sizeof(EDBG_ADDR));    
        *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START + 2*EDBG_DFLT_BUFFER_POOL_SIZE;
        break;            
    default:
        return (FALSE);
    }
    return (TRUE);
}



/* OEMEthGetSecs
 *
 *  Return a count of seconds from some arbitrary time (the absolute value is not important,
 *  so long as it increments appropriately). Read this value from the RTC values in CMOS. Note
 *  that reading the CMOS requires multiple register operations, so this function must be called
 *  only when scheduling is disabled.
 */
static DWORD dwLastTime;  // For making sure we aren't running backward
extern BOOL fRTCInit;
extern BOOL Bare_GetRealTime(LPSYSTEMTIME lpst);
extern volatile DWORD CurMSec;

DWORD
OEMEthGetSecs()
{
    SYSTEMTIME st;
    DWORD dwRet;
    static DWORD dwBias;

    if (!fRTCInit) {
        Bare_GetRealTime( &st );
        dwRet = ((60UL * (60UL * (24UL * (31UL * st.wMonth + st.wDay) + st.wHour) + st.wMinute)) + st.wSecond);
        dwBias = dwRet;
    } else {
        dwRet = (CurMSec/1000) + dwBias;
    }

    if (dwRet < dwLastTime) {
        EdbgOutputDebugString("! Time went backwards (or wrapped): cur: %u, last %u\n",
                              dwRet,dwLastTime);
    }
    dwLastTime = dwRet;
    return (dwRet);
}

#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
    {
        //
        //  Eth driver does not yet support filter setting
        //  So if it is PACKET_TYPE_DIRECTED, PACKET_TYPE_MULTICAST, 
        //  PACKET_TYPE_BROADCAST, we just indicate 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);   

    //
    //  We can check how many entries an adapter that are attached to 
    //  can support.
    //  To make things simple, we just assume we can support minimum that
    //  vmini thinks we support (i.e. 8).
    //

    if (dwNoOfAddresses > 8)
    {
        //
        //  This should never happen, since VMINI is known to support
        //  8 entries only... 
        //
        
        EdbgOutputDebugString(
            "Multicast list requeste [%d] > 8 !!!\r\n",
            dwNoOfAddresses);

        return FALSE;
    }


    //
    //   8 entries, 6 bytes each..
    //

    memset(
        ucMultiAddr,
        0x00,
        8 * 6);     

    //
    //  6 bytes per entry..
    //

    memcpy(
        ucMultiAddr,
        pucMulticastAddressList,
        dwNoOfAddresses * 6);


    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)
    {
        //
        //  We are in KernelIOCTL call, some h/w requires the 
        //  setting of the MULTICAST addresses in interrupt service routine.
        //  So we will do it later, and mark it so the ISR will know about it..
        //  Note:
        //  Order is important here.    Don't set bNewMulticast to true until
        //  all the entries and the dwNoOfEntry are properly set up.
        //  This is because we can be switched out in the middle of 
        /// KernelIOCTL!!
        //

        dwNoOfEntry   = dwNoOfAddresses;
        bNewMulticast = TRUE;       
        bReturnValue  = TRUE;
    }
    else
        bReturnValue = FALSE;

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


    return bReturnValue;
    

}   //  OEMEthMulticastList()

#endif

⌨️ 快捷键说明

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