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

📄 ndissend.c

📁 MICREL 网卡驱动 FOR CE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
*/

NDIS_STATUS MiniportSend (
    IN  NDIS_HANDLE  hAdapterContext,
    IN  PNDIS_PACKET pPacket,
    IN  UINT         uiFlags )
{
    PNDIS_ADAPTER pAdapter = ( PNDIS_ADAPTER ) hAdapterContext;
    PHARDWARE     pHardware = &pAdapter->m_Hardware;
    NDIS_STATUS   nsStatus = NDIS_STATUS_FAILURE;
    PNDIS_BUFFER  pndisBuffer;
    UINT          uiPacketLength;
    UINT          uiPhysicalBufferCount;
    UINT          uiBufferCount;
    ULONG         ulInterruptMask;
    int           nCount;

    if ( !AcquireAdapter( pAdapter, FALSE ) )
    {
        goto SendDone;
    }

#ifdef DEBUG_COUNTER
    pHardware->m_nGood[ COUNT_GOOD_SEND_PACKET ]++;
#endif
    NdisQueryPacket( pPacket, &uiPhysicalBufferCount, &uiBufferCount,
        &pndisBuffer, &uiPacketLength );

    // If the returned packet length is zero, there is nothing to transmit.
    if ( !uiPacketLength )
    {
#ifdef DEBUG_COUNTER
        pHardware->m_nGood[ COUNT_GOOD_SEND_ZERO ]++;
#endif
        nsStatus = NDIS_STATUS_SUCCESS;
        goto SendLockDone;
    }

    /* Save the current interrupt mask and block all interrupts. */
    ulInterruptMask = HardwareBlockInterrupt( pHardware );

    if ( ( int ) uiBufferCount > pAdapter->m_cnMapRegAvail )
    {
        nCount = HardwareAllocPacket( pHardware, uiPacketLength, 1 );
    }
    else
        nCount = HardwareAllocPacket( pHardware, uiPacketLength,
            uiPhysicalBufferCount );
    if ( !nCount )
    {
        nsStatus = NDIS_STATUS_RESOURCES;
        goto SendLockDone;
    }

    if ( nCount > ( int ) uiBufferCount )
    {
        nsStatus = SendBuffers( pAdapter, pPacket, pndisBuffer, uiPacketLength,
            uiBufferCount );
    }
    else
        nsStatus = SendPacket( pAdapter, pPacket, pndisBuffer, uiPacketLength );

    /* Restore the interrupt mask. */
    HardwareSetInterrupt( pHardware, ulInterruptMask );

SendLockDone:
    ReleaseAdapter( pAdapter );

SendDone:
    NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
    return( nsStatus );
}  // MiniportSend

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

/*
    AdapterTransmitQueueLength

    Description:
        This function returns the number of packets waiting in the transmit
        queue.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

    Return (ULONG):
        The number of packets in the send queue.
*/

ULONG AdapterTransmitQueueLength (
    IN  PNDIS_ADAPTER pAdapter )
{
    PNDIS_PACKET pPacket;
    ULONG        ulCount = 0;

    if ( !AcquireAdapter( pAdapter, FALSE ) )
        return( NUM_OF_TX_DESC );

    pPacket = pAdapter->m_pPacketQueueHead;
    while ( pPacket )
    {
        ++ulCount;
        pPacket = RESERVED( pPacket )->Next;
    }
    ReleaseAdapter( pAdapter );
    return( ulCount );
}  // AdapterTransmitQueueLength


#ifdef SEND_QUEUE
/*
    AddPacketToTransmitQueue

    Description:
        This routine adds packets to the transmit queue.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

        PNDIS_PACKET pPacket
            Pointer to NDIS packet.

    Return (None):
*/

void AddPacketToTransmitQueue (
    PNDIS_ADAPTER pAdapter,
    PNDIS_PACKET  pPacket )
{
    if ( pAdapter->m_pPacketQueueTail )
        RESERVED( pAdapter->m_pPacketQueueTail )->Next = pPacket;
    else
        pAdapter->m_pPacketQueueHead = pPacket;
    RESERVED( pPacket )->Next = NULL;
    pAdapter->m_pPacketQueueTail = pPacket;
    NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_PENDING );
}  // AddPacketToTransmitQueue


/*
    SendNextPacket

    Description:
        This routine is used to send the next packet waiting in the queue.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

    Return (None):
*/

void SendNextPacket (
    PNDIS_ADAPTER pAdapter )
{
    PHARDWARE    pHardware = &pAdapter->m_Hardware;
    NDIS_STATUS  nsStatus;
    PNDIS_PACKET pPacket;
    PNDIS_BUFFER pndisBuffer;
    UINT         uiPacketLength;
    UINT         uiBufferCount;
    UINT         uiPhysicalBufferCount;
    int          nCount;

    if ( !AcquireAdapter( pAdapter, FALSE ) )
    {
        return;
    }

    // Return if we don't have a packet to send.
    if ( !pAdapter->m_pPacketQueueHead )
    {
#ifdef DEBUG_COUNTER
        pHardware->m_nGood[ COUNT_GOOD_NO_NEXT_PACKET ]++;
#endif
        goto SendNextPacketDone;
    }

    pPacket = pAdapter->m_pPacketQueueHead;

    NdisQueryPacket( pPacket, &uiPhysicalBufferCount, &uiBufferCount,
        &pndisBuffer, &uiPacketLength );

    // If the returned packet length is zero, there is nothing to transmit.
    if ( !uiPacketLength )
    {
#ifdef DEBUG_COUNTER
        pHardware->m_nGood[ COUNT_GOOD_SEND_ZERO ]++;
#endif
        nsStatus = NDIS_STATUS_SUCCESS;
        NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
        goto SendNextDone;
    }

    if ( ( int ) uiBufferCount > pAdapter->m_cnMapRegAvail )
    {
        nCount = HardwareAllocPacket( pHardware, uiPacketLength, 1 );
    }
    else
        nCount = HardwareAllocPacket( pHardware, uiPacketLength,
            uiPhysicalBufferCount );
    if ( !nCount )
    {
        goto SendNextPacketDone;
    }

    if ( nCount > ( int ) uiBufferCount )
    {
        nsStatus = SendBuffers( pAdapter, pPacket, pndisBuffer, uiPacketLength,
            uiBufferCount );
    }
    else
        nsStatus = SendPacket( pAdapter, pPacket, pndisBuffer, uiPacketLength );

SendNextDone:

    // Remove the packet from the queue.
#ifdef DEBUG_COUNTER
    pHardware->m_nGood[ COUNT_GOOD_NEXT_PACKET ]++;
#endif
    pAdapter->m_pPacketQueueHead = RESERVED( pPacket )->Next;
    if ( pPacket == pAdapter->m_pPacketQueueTail )
        pAdapter->m_pPacketQueueTail = NULL;

SendNextPacketDone:
    ReleaseAdapter( pAdapter );
}  // SendNextPacket
#endif


/*
    MiniportSendPackets

    Description:
        This routine sends one or more packets in NDIS 4.0.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

        PPNDIS_PACKET pPacketArray
            Array of pointers to NDIS packets.

        UINT uiCount
            Number of packets in the array.

    Return (None):
*/

VOID MiniportSendPackets (
    IN  NDIS_HANDLE   hAdapterContext,
    IN  PPNDIS_PACKET pPacketArray,
    IN  UINT          uiCount )
{
    PNDIS_ADAPTER pAdapter = ( PNDIS_ADAPTER ) hAdapterContext;
    NDIS_STATUS   nsStatus;
    PNDIS_PACKET  pPacket;
    PNDIS_BUFFER  pndisBuffer;
    PHARDWARE     pHardware = &pAdapter->m_Hardware;
    UINT          uiIndex;
    UINT          uiPacketLength;
    UINT          uiBufferCount;
    UINT          uiPhysicalBufferCount;
    ULONG         ulInterruptMask;
    int           nCount;

    // If the count of packets in the array is zero, exit after noting this
    // fact.
    if ( !uiCount )
    {

#ifdef DEBUG_COUNTER
        pHardware->m_nBad[ COUNT_BAD_SEND_ZERO ]++;
#endif
        return;
    }

    // Acquire the hardware to avoid having 2 threads messing with the adapter
    // at the same time.  If this can't happen, return all of the packets with
    // a failure indication and exit.
    if ( !AcquireAdapter( pAdapter, FALSE ) )
    {
        for ( uiIndex = 0; uiIndex < uiCount; uiIndex++ )
        {
            pPacket = pPacketArray[ uiIndex ];
            NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_FAILURE );
        }
        return;
    }

    /* Save the current interrupt mask and block all interrupts. */
    ulInterruptMask = HardwareBlockInterrupt( pHardware );

    // The following 'for' loop handles one packet in the array each time
    // through.

    for ( uiIndex = 0; uiIndex < uiCount; uiIndex++ )
    {
        // Count packets sent.  Point pPacket to the next packet in the array.
#ifdef DEBUG_COUNTER
        pHardware->m_nGood[ COUNT_GOOD_SEND_PACKET ]++;
#endif
        pPacket = pPacketArray[ uiIndex ];

#ifdef SEND_QUEUE
        // If there are packets waiting in the queue to be transmitted add this
        // packet to the end of that queue.  We have to keep things in order.
        if ( pAdapter->m_pPacketQueueTail )
        {
#ifdef DEBUG_COUNTER
            pHardware->m_nGood[ COUNT_GOOD_SEND_QUEUE ]++;
#endif
            AddPacketToTransmitQueue( pAdapter, pPacket );
        }
        else
#endif
        {
            NdisQueryPacket( pPacket, &uiPhysicalBufferCount, &uiBufferCount,
                &pndisBuffer, &uiPacketLength );

            // If the returned packet length is zero, there is nothing to
            // transmit.
            if ( !uiPacketLength )
            {
#ifdef DEBUG_COUNTER
                pHardware->m_nGood[ COUNT_GOOD_SEND_ZERO ]++;
#endif
                NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_SUCCESS );
                continue;
            }

#if 1
            if ( ( int ) uiBufferCount > pAdapter->m_cnMapRegAvail )
#else
            if ( ( int ) uiBufferCount > 0  )
#endif
            {
                nCount = HardwareAllocPacket( pHardware, uiPacketLength, 1 );
            }
            else
                nCount = HardwareAllocPacket( pHardware, uiPacketLength,
                    uiPhysicalBufferCount );
            if ( nCount > ( int ) uiBufferCount )
            {
                nsStatus = SendBuffers( pAdapter, pPacket, pndisBuffer,
                    uiPacketLength, uiBufferCount );

                NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
            }
            else if ( !nCount )
            {

#ifdef SEND_QUEUE
                AddPacketToTransmitQueue( pAdapter, pPacket );

#else
                NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_FAILURE );
#endif
            }
            else
            {
                nsStatus = SendPacket( pAdapter, pPacket, pndisBuffer,
                    uiPacketLength );

                NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
            }
        }
    }

    /* Restore the interrupt mask. */
    HardwareSetInterrupt( pHardware, ulInterruptMask );

    ReleaseAdapter( pAdapter );
}  // MiniportSendPackets

⌨️ 快捷键说明

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