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

📄 ndisoid.c

📁 MICREL 网卡驱动 FOR CE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ---------------------------------------------------------------------------
          Copyright (c) 2003-2006 Micrel, Inc.  All rights reserved.
   ---------------------------------------------------------------------------

    NdisOid.c - NDIS driver OID query functions.

    Author      Date        Description
    THa         12/01/03    Created file.
    THa         06/27/05    Updated for version 0.1.5.
    THa         02/23/06    Updated for WinCE 5.0.
    THa         04/13/06    Add EEPROM access support.
    THa         06/02/06    Report statistics from MIB counters.
    THa         07/27/06    Version 1.4 supports NDIS 5.
   ---------------------------------------------------------------------------
*/


#include "target.h"
#include "NdisDevice.h"
#include "NdisOid.h"


/* -------------------------------------------------------------------------- */

#define OID_DEVICE_MODE  0xff0100cc

// List of supported OID for this driver

NDIS_OID SupportedOids[] =
{
    OID_GEN_SUPPORTED_LIST,
    OID_GEN_HARDWARE_STATUS,
    OID_GEN_MEDIA_SUPPORTED,
    OID_GEN_MEDIA_IN_USE,
    OID_GEN_MAXIMUM_LOOKAHEAD,
    OID_GEN_MAXIMUM_FRAME_SIZE,
    OID_GEN_LINK_SPEED,
    OID_GEN_TRANSMIT_BUFFER_SPACE,
    OID_GEN_RECEIVE_BUFFER_SPACE,
    OID_GEN_TRANSMIT_BLOCK_SIZE,
    OID_GEN_RECEIVE_BLOCK_SIZE,
    OID_GEN_VENDOR_ID,
    OID_GEN_VENDOR_DESCRIPTION,
    OID_GEN_CURRENT_PACKET_FILTER,
    OID_GEN_CURRENT_LOOKAHEAD,
    OID_GEN_DRIVER_VERSION,
    OID_GEN_MAXIMUM_TOTAL_SIZE,
    OID_GEN_PROTOCOL_OPTIONS,
    OID_GEN_MAC_OPTIONS,
    OID_GEN_MEDIA_CONNECT_STATUS,
    OID_GEN_MAXIMUM_SEND_PACKETS,
    OID_GEN_VENDOR_DRIVER_VERSION,

    OID_802_3_PERMANENT_ADDRESS,
    OID_802_3_CURRENT_ADDRESS,
    OID_802_3_MAXIMUM_LIST_SIZE,
    OID_802_3_MULTICAST_LIST,

    OID_GEN_XMIT_OK,
    OID_GEN_RCV_OK,
    OID_GEN_XMIT_ERROR,
    OID_GEN_RCV_ERROR,
    OID_GEN_RCV_NO_BUFFER,

    OID_GEN_DIRECTED_FRAMES_XMIT,
    OID_GEN_MULTICAST_FRAMES_XMIT,
    OID_GEN_BROADCAST_FRAMES_XMIT,
    OID_GEN_DIRECTED_FRAMES_RCV,
    OID_GEN_MULTICAST_FRAMES_RCV,
    OID_GEN_BROADCAST_FRAMES_RCV,

    OID_GEN_RCV_CRC_ERROR,

    OID_802_3_RCV_ERROR_ALIGNMENT,
    OID_802_3_XMIT_ONE_COLLISION,
    OID_802_3_XMIT_MORE_COLLISIONS,

    OID_802_3_XMIT_DEFERRED,
    OID_802_3_XMIT_MAX_COLLISIONS,
    OID_802_3_XMIT_LATE_COLLISIONS,

#if 0
    OID_GEN_PHYSICAL_MEDIUM,
#endif

#if (NDISVER >= 50)
     OID_PNP_CAPABILITIES,
     OID_PNP_SET_POWER,
     OID_PNP_QUERY_POWER,
     OID_PNP_ADD_WAKE_UP_PATTERN,
     OID_PNP_REMOVE_WAKE_UP_PATTERN,
     OID_PNP_ENABLE_WAKE_UP,
     OID_PNP_WAKE_UP_OK,
     OID_PNP_WAKE_UP_ERROR,
#endif
};

/* -------------------------------------------------------------------------- */

static
NDIS_STATUS QueryTaskOffload (
    IN  PNDIS_ADAPTER             pAdapter,
    IN  ULONG                     ulBufferLength,
    OUT PNDIS_TASK_OFFLOAD_HEADER pOffLoadHeader,
    OUT PULONG                    pulBytesNeeded,
    OUT PULONG                    pulBytesWritten )
{
    NDIS_TASK_OFFLOAD         *pTaskOffLoad;
    NDIS_TASK_TCP_IP_CHECKSUM *pCheckSum;
    UINT                       uiMoveBytes;

    uiMoveBytes = sizeof( NDIS_TASK_OFFLOAD_HEADER ) +
        sizeof( NDIS_TASK_OFFLOAD ) +
        sizeof( NDIS_TASK_TCP_IP_CHECKSUM );
    if ( ulBufferLength < uiMoveBytes )
    {
        *pulBytesNeeded = uiMoveBytes;
        return( NDIS_STATUS_INVALID_LENGTH );
    }

    // validatation, according to latest MS's DDK document, it should return NDIS_STATUS_NOT_SUPPORTED
    // if parameters are not supported by the driver
    if ( NDIS_TASK_OFFLOAD_VERSION != pOffLoadHeader->Version  ||
            sizeof( NDIS_TASK_OFFLOAD_HEADER ) != pOffLoadHeader->Size  ||
            IEEE_802_3_Encapsulation !=
            pOffLoadHeader->EncapsulationFormat.Encapsulation )
    {
        return( NDIS_STATUS_NOT_SUPPORTED );
    }

    // tell upper edge protocol driver that we support OFFLOAD task!
    pOffLoadHeader->OffsetFirstTask = sizeof( NDIS_TASK_OFFLOAD_HEADER );

    pOffLoadHeader++;
    pTaskOffLoad = ( NDIS_TASK_OFFLOAD* ) pOffLoadHeader;
    pTaskOffLoad->Version = NDIS_TASK_OFFLOAD_VERSION;
    pTaskOffLoad->Size = sizeof( NDIS_TASK_OFFLOAD );
    pTaskOffLoad->Task = TcpIpChecksumNdisTask;

    // currently supports only one TASK_OFFLOAD
    pTaskOffLoad->OffsetNextTask = 0;
    pTaskOffLoad->TaskBufferLength = sizeof( NDIS_TASK_TCP_IP_CHECKSUM );

    // fill task buffer
    pCheckSum = ( NDIS_TASK_TCP_IP_CHECKSUM* ) pTaskOffLoad->TaskBuffer;

    if ( pAdapter->m_ulTxChecksum )
    {
        // Need to verify IpOptionsSupported and TcpOptionsSupported support, user select options?
        pCheckSum->V4Transmit.IpOptionsSupported = FALSE;
        pCheckSum->V4Transmit.TcpOptionsSupported = FALSE;
        pCheckSum->V4Transmit.TcpChecksum = TRUE;
        pCheckSum->V4Transmit.UdpChecksum = FALSE;
        pCheckSum->V4Transmit.IpChecksum = TRUE;
    }
    else
    {
        pCheckSum->V4Transmit.IpOptionsSupported = FALSE;
        pCheckSum->V4Transmit.TcpOptionsSupported = FALSE;
        pCheckSum->V4Transmit.TcpChecksum = FALSE;
        pCheckSum->V4Transmit.UdpChecksum = FALSE;
        pCheckSum->V4Transmit.IpChecksum = FALSE;
    }

    if ( pAdapter )
    {
        pCheckSum->V4Receive.IpOptionsSupported = FALSE;
        pCheckSum->V4Receive.TcpOptionsSupported = FALSE;
        pCheckSum->V4Receive.TcpChecksum = TRUE;
        pCheckSum->V4Receive.UdpChecksum = FALSE;
        pCheckSum->V4Receive.IpChecksum = TRUE;
    }
    else
    {
        pCheckSum->V4Receive.IpOptionsSupported = FALSE;
        pCheckSum->V4Receive.TcpOptionsSupported = FALSE;
        pCheckSum->V4Receive.TcpChecksum = FALSE;
        pCheckSum->V4Receive.UdpChecksum = FALSE;
        pCheckSum->V4Receive.IpChecksum = FALSE;
    }

    // we don't support V6 currently
    pCheckSum->V6Transmit.IpOptionsSupported = FALSE;
    pCheckSum->V6Transmit.TcpOptionsSupported = FALSE;
    pCheckSum->V6Transmit.TcpChecksum = FALSE;
    pCheckSum->V6Transmit.UdpChecksum = FALSE;
    pCheckSum->V6Receive.IpOptionsSupported = FALSE;
    pCheckSum->V6Receive.TcpOptionsSupported = FALSE;
    pCheckSum->V6Receive.TcpChecksum = FALSE;
    pCheckSum->V6Receive.UdpChecksum = FALSE;

    *pulBytesWritten += uiMoveBytes;

#if DBG
DBG_PRINT( "query offload: %u"NEWLINE, *pulBytesWritten );
#endif
    return( NDIS_STATUS_SUCCESS );
}  /* QueryTaskOffload */


static
NDIS_STATUS SetTaskOffload (
    IN  PNDIS_ADAPTER             pAdapter,
    IN  PNDIS_TASK_OFFLOAD_HEADER pOffLoadHeader,
    OUT PULONG                    pulBytesRead )
{
    NDIS_TASK_OFFLOAD         *pTaskOffLoad;
    NDIS_TASK_TCP_IP_CHECKSUM *pCheckSum;
    BOOLEAN                    bFound;
    NDIS_STATUS                NdisStatus = NDIS_STATUS_SUCCESS;

    // validatation again?
    if ( sizeof( NDIS_TASK_OFFLOAD_HEADER ) != pOffLoadHeader->Size  ||
            NDIS_TASK_OFFLOAD_VERSION != pOffLoadHeader->Version  ||
            IEEE_802_3_Encapsulation !=
            pOffLoadHeader->EncapsulationFormat.Encapsulation )
    {
        return( NDIS_STATUS_NOT_SUPPORTED );
    }
    *pulBytesRead += sizeof( NDIS_TASK_OFFLOAD_HEADER );

    // if disable NIC's all offload caps
    if ( 0 == pOffLoadHeader->OffsetFirstTask )
    {
        if ( pAdapter->m_ulTxChecksum )
        {
            // We can't modify the TX mode register directly if it is running,
            // so call a newly created (in reset.c) function instead
            pAdapter->m_ulTxChecksum &= ~(
                TASK_OFFLOAD_IP_CHECKSUM |
                TASK_OFFLOAD_TCP_CHECKSUM |
                TASK_OFFLOAD_UDP_CHECKSUM );
        }
        if ( pAdapter->m_ulRxChecksum )
        {
            pAdapter->m_ulRxChecksum &= ~(
                TASK_OFFLOAD_IP_CHECKSUM |
                TASK_OFFLOAD_TCP_CHECKSUM |
                TASK_OFFLOAD_UDP_CHECKSUM );
        }
        return NdisStatus;
    }

    /* Look through task chain to see whether suitable task(s) were set by the
       upper edge driver and take the last one to set.
    */
    pTaskOffLoad = ( NDIS_TASK_OFFLOAD* )(( PUCHAR ) pOffLoadHeader +
        pOffLoadHeader->OffsetFirstTask );
    bFound = FALSE;
    while ( pTaskOffLoad )
    {
        *pulBytesRead += sizeof( NDIS_TASK_OFFLOAD );

        /* Check to see whether it is the checksum task we support. */
        if ( TcpIpChecksumNdisTask == pTaskOffLoad->Task )
        {
            pCheckSum = ( NDIS_TASK_TCP_IP_CHECKSUM* )
                pTaskOffLoad->TaskBuffer;
            *pulBytesRead += sizeof( NDIS_TASK_TCP_IP_CHECKSUM );

            /* We need to detect to see whether unsupported settings are passed
               from upper edge before following the instruction.
            */
            if ( pCheckSum->V4Transmit.TcpOptionsSupported  ||
                    pCheckSum->V4Transmit.IpOptionsSupported )
            {
                pCheckSum->V4Transmit.TcpOptionsSupported = FALSE;
                pCheckSum->V4Transmit.IpOptionsSupported = FALSE;
                return NDIS_STATUS_NOT_SUPPORTED;
            }
            if ( pCheckSum->V4Receive.TcpOptionsSupported  ||
                    pCheckSum->V4Receive.IpOptionsSupported )
            {
                pCheckSum->V4Receive.TcpOptionsSupported = FALSE;
                pCheckSum->V4Receive.IpOptionsSupported = FALSE;
                return NDIS_STATUS_NOT_SUPPORTED;
            }
            bFound = TRUE;
            if ( pAdapter->m_ulTxChecksum )
            {
                if ( pCheckSum->V4Transmit.TcpChecksum )
                    pAdapter->m_ulTxChecksum |= TASK_OFFLOAD_TCP_CHECKSUM;
                if ( pCheckSum->V4Transmit.UdpChecksum )
                    pAdapter->m_ulTxChecksum |= TASK_OFFLOAD_UDP_CHECKSUM;
                if ( pCheckSum->V4Transmit.IpChecksum )
                    pAdapter->m_ulTxChecksum |= TASK_OFFLOAD_IP_CHECKSUM;
            }
            if ( pAdapter->m_ulRxChecksum )
            {
                if ( pCheckSum->V4Receive.TcpChecksum )
                    pAdapter->m_ulRxChecksum |= TASK_OFFLOAD_TCP_CHECKSUM;
                if ( pCheckSum->V4Receive.UdpChecksum )
                    pAdapter->m_ulRxChecksum |= TASK_OFFLOAD_UDP_CHECKSUM;
                if ( pCheckSum->V4Receive.IpChecksum )
                    pAdapter->m_ulRxChecksum |= TASK_OFFLOAD_IP_CHECKSUM;
            }
        }

        /* To next offload task if any. */
        if ( 0 == pTaskOffLoad->OffsetNextTask )
            break;

        pTaskOffLoad = ( NDIS_TASK_OFFLOAD* )(( PUCHAR ) pTaskOffLoad +
            pTaskOffLoad->OffsetNextTask );
    }

#if DBG
DBG_PRINT( "checksum offload: %x %x; %u"NEWLINE, pAdapter->m_ulRxChecksum,
    pAdapter->m_ulTxChecksum, *pulBytesRead );
#endif

    return( FALSE == bFound ? NDIS_STATUS_NOT_SUPPORTED : NdisStatus );
}  /* SetTaskOffload */


#if (NDISVER >= 50)  ||  defined( UNDER_CE )
static
NDIS_STATUS AddWakeUpPattern (
    IN  PNDIS_ADAPTER           pAdapter,
    IN  PNDIS_PM_PACKET_PATTERN pPattern,
    OUT PULONG                  pulBytesRead )
{
    NDIS_STATUS     NdisStatus;
    PWAKE_UP_PACKET pWakeUpPacket;

    if ( pAdapter->m_cnWakeUpPacket < MAX_WAKE_UP_PACKET  &&
            pPattern->MaskSize <= MAX_PATTERN_LENGTH / 8  &&
            pPattern->PatternSize <= MAX_PATTERN_LENGTH )
    {
        /* Move the packet pattern separately in case they are not
           continuous.
        */
        pWakeUpPacket = &pAdapter->WakeUpPacket[
            pAdapter->m_cnWakeUpPacket ];
        pAdapter->m_cnWakeUpPacket++;

        /* Copy the NDIS_PM_PACKET_PATTERN. */
        pWakeUpPacket->NdisPacketPattern = *pPattern;
        pWakeUpPacket->NdisPacketPattern.PatternOffset =
            sizeof( NDIS_PM_PACKET_PATTERN ) + pPattern->MaskSize;
        *pulBytesRead += sizeof( NDIS_PM_PACKET_PATTERN );

        /* Copy the MASK. */
        NdisMoveMemory(
            &pWakeUpPacket->MaskAndPattern[ 0 ], ( pPattern + 1 ),
            pPattern->MaskSize );
        *pulBytesRead += pPattern->MaskSize;

        /* Copy the PATTERN. */
        NdisMoveMemory(
            &pWakeUpPacket->MaskAndPattern[ pPattern->MaskSize ],
            ( PUCHAR ) pPattern + pPattern->PatternOffset,
            pPattern->PatternSize );
        *pulBytesRead += pPattern->PatternSize;

#if DBG
{
    UINT i;

    for ( i = 0; i < pPattern->MaskSize; i++ )
        DBG_PRINT( "%02X ", pWakeUpPacket->MaskAndPattern[ i ]);
    DBG_PRINT( NEWLINE );
    for ( ; i < pPattern->MaskSize + pPattern->PatternSize; i++ )
        DBG_PRINT( "%02X ", pWakeUpPacket->MaskAndPattern[ i ]);
    DBG_PRINT( NEWLINE );
}
DBG_PRINT( "Added: %u"NEWLINE, *pulBytesRead );
#endif
#if 0
        SetWakeupRegs(pAdapter, pAdapter->nWakeUpPacketCount - 1);
#endif

        NdisStatus = NDIS_STATUS_SUCCESS;
    }
    else
    {
        *pulBytesRead = 0;
        NdisStatus = NDIS_STATUS_RESOURCES;
    }

    return NdisStatus;
}  /* AddWakeUpPattern */


static
NDIS_STATUS RemoveWakeUpPattern (
    IN  PNDIS_ADAPTER           pAdapter,
    IN  PNDIS_PM_PACKET_PATTERN pPattern,
    OUT PULONG                  pulBytesRead )
{
    NDIS_STATUS     NdisStatus;
    PWAKE_UP_PACKET pWakeUpPacket;
    UINT            nCount;
    int             nIndex;
    PUCHAR          pSource;
    PUCHAR          pTarget;

    for ( nIndex = 0; nIndex < pAdapter->m_cnWakeUpPacket; nIndex++ )
    {
        pWakeUpPacket = &pAdapter->WakeUpPacket[ nIndex ];
        if ( pPattern->MaskSize == pWakeUpPacket->NdisPacketPattern.MaskSize
                &&  pPattern->PatternSize ==
                pWakeUpPacket->NdisPacketPattern.PatternSize )
        {
            /* Compare the mask. */
            for ( nCount = 0,
                    pSource = ( PUCHAR ) pPattern +
                    sizeof( NDIS_PM_PACKET_PATTERN ),
                    pTarget = pWakeUpPacket->MaskAndPattern;
                    nCount < pWakeUpPacket->NdisPacketPattern.MaskSize;
                    nCount++ )
                if ( pSource[ nCount ] != pTarget[ nCount ] )
                    break;
            if ( nCount < pWakeUpPacket->NdisPacketPattern.MaskSize )
                continue;

            /* Compare the pattern. */
            for ( nCount = 0,
                    pSource = ( PUCHAR ) pPattern + pPattern->PatternOffset,
                    pTarget = &pWakeUpPacket->MaskAndPattern[
                        pPattern->MaskSize ];
                    nCount < pWakeUpPacket->NdisPacketPattern.PatternSize;
                    nCount++ )
                if ( pSource[ nCount ] != pTarget[ nCount ] )
                    break;
            if ( nCount == pWakeUpPacket->NdisPacketPattern.PatternSize )
                break;
        }
    }

    if ( nIndex < pAdapter->m_cnWakeUpPacket )
    {
        for ( ; nIndex < pAdapter->m_cnWakeUpPacket; nIndex++ )
            pAdapter->WakeUpPacket[ nIndex ] =
                pAdapter->WakeUpPacket[ nIndex + 1 ];
        pAdapter->m_cnWakeUpPacket--;

⌨️ 快捷键说明

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