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

📄 ndisisr.c

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

    NdisISR.c - NDIS driver interrupt processing.

    Author      Date        Description
    THa         12/01/03    Created file.
    THa         06/27/05    Updated for version 0.1.5.
    THa         09/29/05    Changed descriptor structure.
    THa         02/23/06    Updated for WinCE 5.0.
    THa         06/02/06    Report statistics from MIB counters.
   ---------------------------------------------------------------------------
*/


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


#if 0
#define RCV_UNTIL_NONE
#endif


#ifdef DEBUG_OVERRUN
int receive_overrun = 0;
#endif

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

/*
    ProcessReceive

    Description:
        This function processes the buffer receiving.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

    Return (BOOLEAN):
        TRUE if a packet is received; FALSE otherwise.
*/


int ProcessReceive (
    IN  PNDIS_ADAPTER pAdapter )
{
    int           iNext;
    TDescStat     status;
    PHARDWARE     pHardware = &pAdapter->m_Hardware;
    PTDescInfo    pInfo = &pHardware->m_RxDescInfo;
    PBUFFER_INFO  pBufInfo = &pAdapter->m_RxBufInfo;
    PNDIS_PACKET* PacketArray = pAdapter->m_PacketArray;
    PNDIS_PACKET  pPacket;
    PTDesc        pDesc;
    PDMA_BUFFER   pDma;

#ifndef RCV_UNTIL_NONE
    int           cnLeft = pInfo->cnAlloc;
#endif
    UINT          i;
    UINT          uiPacketCount = 0;

#ifndef NO_STATS
    PUCHAR        pBuffer;
#endif
    int           port = MAIN_PORT;

#ifdef DEBUG_RX_DATA
    int           nLength;
#endif

    iNext = pInfo->iNext;

#ifdef RCV_UNTIL_NONE
    while ( 1 )

#else
    while ( cnLeft-- )
#endif
    {
        /* Get next descriptor which is not hardware owned. */
        GetReceivedPacket( pInfo, iNext, pDesc, status.ulData );
        if ( status.rx.fHWOwned )
            break;

#ifdef CHECK_OVERRUN
        if ( !( pDesc->pCheck->Control.ulData & CPU_TO_LE32( DESC_HW_OWNED )) )
        {

#ifdef DEBUG_OVERRUN
            receive_overrun = 1;
            pHardware->m_ulDropped++;
#endif
            ReleasePacket( pDesc );
            FreeReceivedPacket( pInfo, iNext );

#ifndef RCV_UNTIL_NONE
            cnLeft = pInfo->cnAlloc;
#endif
            continue;
        }
#endif

        pDesc->sw.Control.ulData = status.ulData;
        pInfo->pCurrent = pDesc;

        HardwareReceive( pHardware );

        if ( pHardware->m_nPacketLen )
        {

#ifdef DEBUG_OVERRUN
            pHardware->m_ulReceived++;
#endif

            /* Get received packet information. */
            pDma = DMA_BUFFER( pDesc );

            /* Adjust the length of NDIS buffer to the length of the packet. */
            NdisAdjustBufferLength( pDma->pNdisBuffer,
                pHardware->m_nPacketLen );

            /* Flush the receive buffer. */
            NdisFlushBuffer( pDma->pNdisBuffer, FALSE );
            NdisMUpdateSharedMemory(
                pAdapter->m_hAdapter,
                pDma->ulSize,
                pDma->sm.pVirtual,
                pDma->PhysicalAddr );

#ifndef NO_STATS
            pBuffer = ( PUCHAR ) pDma->sm.pVirtual;

#ifdef DEBUG_RX_DATA
            for ( nLength = 0; nLength < pHardware->m_nPacketLen; nLength++ )
            {
                DbgPrint( "%02X ", pBuffer[ nLength ]);
                if ( ( nLength % 16 ) == 15 )
                {
                    DbgPrint( "\n" );
                }
            }
            DbgPrint( "\n" );
#endif

            /* Descriptor does not have broadcast indication. */
            if ( 0xFF == pBuffer[ 0 ] )
            {
                pHardware->m_cnCounter[ port ]
                    [ OID_COUNTER_BROADCAST_FRAMES_RCV ]++;
                pHardware->m_cnCounter[ port ]
                    [ OID_COUNTER_BROADCAST_BYTES_RCV ] +=
                        pHardware->m_nPacketLen;
                pHardware->m_cnCounter[ port ]
                    [ OID_COUNTER_MULTICAST_FRAMES_RCV ]--;
            }
            else if ( pBuffer[ 0 ] != 0x01 )
            {
                pHardware->m_cnCounter[ port ]
                    [ OID_COUNTER_UNICAST_FRAMES_RCV ]++;

                pHardware->m_cnCounter[ port ]
                    [ OID_COUNTER_DIRECTED_FRAMES_RCV ]++;
                pHardware->m_cnCounter[ port ]
                    [ OID_COUNTER_DIRECTED_BYTES_RCV ] +=
                        pHardware->m_nPacketLen;
            }
#endif
            pHardware->m_cnCounter[ port ][ OID_COUNTER_RCV_OK ]++;

            /* Get pointer of associated packet for further processing. */
            pPacket = pDma->pNdisPacket;

            /* There are buffers available for using in descriptors. */
#ifndef UNDER_CE
            if ( NdisQueryDepthSList( &pBufInfo->listHead ) )

#else
            if ( pBufInfo->cnAvail )
#endif
            {
                /* Upper layer can keep this packet. */
                NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_SUCCESS );

                /* Reset this pointer so that we can debug the RX descriptor if
                   error happens.
                */
                RESERVED( pPacket )->pDesc = NULL;

                /* Get a new buffer for this descriptor. */
                pDma = Alloc_DMA_Buffer( pBufInfo, pDesc );

                /* Set descriptor for packet receive. */
                SetReceiveBuffer( pDesc, pDma->sm.ulPhysical );
                SetReceiveLength( pDesc, pDma->ulSize );
                ReleasePacket( pDesc );
            }
            else
            {
                /* Upper layer must copy this packet immediately. */
                NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_RESOURCES );
                RESERVED( pPacket )->pDesc = pDesc;

                /* Cannot release the descriptor yet. */
            }

            PacketArray[ uiPacketCount ] = pPacket;
            uiPacketCount++;
        }
        else
        {
            ReleasePacket( pDesc );
        }

        FreeReceivedPacket( pInfo, iNext );
    }
    pInfo->iNext = iNext;

    if ( uiPacketCount )
    {
        /* We have packets to indicate. */
        NdisMIndicateReceivePacket( pAdapter->m_hAdapter, PacketArray,
            uiPacketCount );

        /* Determine which packets are kept for reuse and which ones are needed
           to put back to the list.
        */
        for ( i = 0; i < uiPacketCount; i++ )
        {
            pPacket = PacketArray[ i ];
            if ( NDIS_STATUS_PENDING != NDIS_GET_PACKET_STATUS( pPacket ) )
            {
                /* If the status code for the packet is not status pending,
                   which should be modified by NdisMIndicateReceivePacket
                   function, then we can place the resouces back on the free
                   list.
                */
                pDma = RESERVED( pPacket )->pDma;

#if 0
                /* Adjust the buffer length. */
                NdisAdjustBufferLength( pDma->pNdisBuffer, pDma->ulSize );
#endif

                /* If we indicate to the upper that it could not keep this
                   packet then do not place it back to the list.
                */
                if ( NDIS_STATUS_RESOURCES ==
                        NDIS_GET_PACKET_STATUS( pPacket ) )
                {
                    pDesc = RESERVED( pPacket )->pDesc;

                    /* It is set by us so release the descriptor. */
                    if ( pDesc )
                    {
                        RESERVED( pPacket )->pDesc = NULL;
                        ReleasePacket( pDesc );
                    }

                    /* It should not happen unless upper layer really has no
                       resources.
                    */
                    else
                    {
                        /* Place the buffer back to the free list for use next
                           time.
                        */
                        Free_DMA_Buffer( pBufInfo, pDma );
                    }
                }
                else
                {

⌨️ 快捷键说明

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