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

📄 ndissend.c

📁 MICREL 网卡驱动 FOR CE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
        UINT uiPacketLength
            Length of the packet.

        UINT uiBufferCount
            Number of buffers.

    Return (NDIS_STATUS):
        NDIS_STATUS_PENDING if successful; otherwise, an error code indicating
        failure.
*/

NDIS_STATUS SendBuffers (
    PNDIS_ADAPTER pAdapter,
    PNDIS_PACKET  pPacket,
    PNDIS_BUFFER  pndisBuffer,
    UINT          uiPacketLength,
    UINT          uiBufferCount )
{
    PTDesc                     pDesc;
    PTDesc                     pLastDesc;
    PTDesc                     pFirstDesc;
    PDMA_BUFFER                pDma;
    PHARDWARE                  pHardware = &pAdapter->m_Hardware;
    PTDescInfo                 pInfo = &pHardware->m_TxDescInfo;
    NDIS_STATUS                nsStatus = NDIS_STATUS_FAILURE;
    TDesc                      BufDesc;
    NDIS_PHYSICAL_ADDRESS_UNIT PhySegArray[ DRV_PACKET_ARRAY_SIZE ];
    UINT                       uiPhySegCount;
    UINT                       uiBuf;
    UINT                       uiSeg;
#if 0
    UINT                       uiLength;
    BOOLEAN                    bBroadcast;
#endif
    int                        port = MAIN_PORT;

    /* Remember the very first descriptor. */
    pFirstDesc = pInfo->pCurrent;
    pDesc = pFirstDesc;
    pLastDesc = pFirstDesc;

#if 0
{
    UINT   uiBufferLength;
    PUCHAR pBuffer = GetFirstBuffer( &pndisBuffer, &uiBufferLength );

    if ( pBuffer  &&  ( pBuffer[ 0 ] & 0x01 ) )
    {
        bBroadcast = TRUE;
    }
    else
    {
        bBroadcast = FALSE;
    }
}
#endif

    for ( uiBuf = 0; uiBuf < uiBufferCount; uiBuf++ )
    {

#if 0
        // want length only
        NdisQueryBuffer( pndisBuffer, NULL, &uiLength );
        if ( 0 == uiLength )
        {
            continue;
        }
#endif

        pDma = Alloc_DMA_Buffer( &pAdapter->m_TxBufInfo, &BufDesc );

        /* Get free map register. */
        pDma->pMapReg = AllocMapReg( pAdapter );
        pDma->pMapReg->pNdisBuffer = pndisBuffer;

        /* Get the mapping of the physical segments. */
        NdisMStartBufferPhysicalMapping(
            pAdapter->m_hAdapter,
            pndisBuffer,                // Buffer
            pDma->pMapReg->uiRegister,  // PhysicalMapRegister
            TRUE,                       // WriteToDevice
            PhySegArray,                // PhysicalAddressArray
            &uiPhySegCount              // ArraySize
            );
#ifdef DBG
        if ( uiPhySegCount )
#endif
        {
            for ( uiSeg = 0; uiSeg < uiPhySegCount; uiSeg++ )
            {
#ifdef DBG
                if ( PhySegArray[ uiSeg ].Length )
#endif
                {

                    /* Release this descriptor to hardware if not the very
                       first one, not wanting the hardware to start
                       transmitting this packet when descriptors are being set.
                    */
                    if ( pLastDesc != pFirstDesc )
                        ReleasePacket( pLastDesc );

                    SetTransmitBuffer( pDesc,
                        ( ULONG ) NdisGetPhysicalAddressLow(
                        PhySegArray[ uiSeg ].PhysicalAddress ));
                    SetTransmitLength( pDesc,
                        PhySegArray[ uiSeg ].Length );

                    /* Remember the last descriptor. */
                    pLastDesc = pDesc;

                    /* Allocate more descriptor. */
                    GetTxPacket( pInfo, pDesc );
                }
            }

            /* If more than one descriptor is used for this buffer, move the
               buffer so that the mapping is freed only after all descriptors
               are transmitted.
            */
            pLastDesc->pReserved = BufDesc.pReserved;
        }

#ifdef DBG
        else
        {
            NdisMCompleteBufferPhysicalMapping(
                pAdapter->m_hAdapter, pndisBuffer, pDma->pMapReg->uiRegister );

            /* Recycle this map register. */
            FreeMapReg( pAdapter, pDma->pMapReg );
            pDma->pMapReg = NULL;

            Free_DMA_Buffer( &pAdapter->m_TxBufInfo, pDma );

            do
            {
                HardwareFreeTxPacket( pInfo );
                pDesc = &pInfo->pRing[ pInfo->iNext ];
                ReleaseDescriptor( pDesc, pDesc->sw.Control );
            } while ( pDesc != pFirstDesc );
            goto SendBuffersDone;
        }
#endif

        /* Flush buffer. */
        NdisFlushBuffer( pndisBuffer, TRUE );

        /* Get next buffer. */
        NdisGetNextBuffer( pndisBuffer, &pndisBuffer );
    }

    /* One more descriptor is allocated. */
    HardwareFreeTxPacket( pInfo );

    /* The last descriptor holds the packet so that it can be returned to
       network subsystem after all descriptors are transmitted.
    */
    pDma->pNdisPacket = pPacket;

    /* pCurrent points to the last descriptor. */
    pInfo->pCurrent = pLastDesc;

    /* Release the first descriptor. */
    ReleasePacket( pFirstDesc );

    if ( HardwareSendPacket( pHardware ) )
    {
        nsStatus = NDIS_STATUS_PENDING;
        pHardware->m_cnCounter[ port ][ OID_COUNTER_XMIT_OK ]++;

#ifndef NO_STATS
        if ( bBroadcast )
        {
            pHardware->m_cnCounter[ port ]
                [ OID_COUNTER_BROADCAST_FRAME_XMIT ]++;
            pHardware->m_cnCounter[ port ]
                [ OID_COUNTER_BROADCAST_BYTES_XMIT ] += uiPacketLength;
        }
        else
        {
            pHardware->m_cnCounter[ port ]
                [ OID_COUNTER_DIRECTED_FRAMES_XMIT ]++;
            pHardware->m_cnCounter[ port ]
                [ OID_COUNTER_DIRECTED_BYTES_XMIT ] += uiPacketLength;
        }
#endif
    }

#ifdef DBG
SendBuffersDone:
#endif

    return( nsStatus );
}  // SendBuffers

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

/*
    TransmitDone

    Description:
        This routine cleans up the descriptors after transmission.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

    Return (None):
*/

VOID TransmitDone (
    PNDIS_ADAPTER pAdapter )
{
    int         iLast;
    TDescStat   status;
    PHARDWARE   pHardware = &pAdapter->m_Hardware;
    PTDescInfo  pInfo = &pHardware->m_TxDescInfo;
    PTDesc      pDesc;
    PDMA_BUFFER pDma;

    iLast = pInfo->iLast;

    while ( pInfo->cnAvail < pInfo->cnAlloc )
    {
        /* Get next descriptor which is not hardware owned. */
        GetTransmittedPacket( pInfo, iLast, pDesc, status.ulData );
        if ( status.tx.fHWOwned )
            break;

        pDma = DMA_BUFFER( pDesc );

        /* This descriptor contains a buffer. */
        if ( pDma )
        {
            /* It is a mapped buffer. */
            if ( pDma->pMapReg )
            {
                /* Ask network subsystem to free the mapping. */
                NdisMCompleteBufferPhysicalMapping(
                    pAdapter->m_hAdapter,
                    pDma->pMapReg->pNdisBuffer,
                    pDma->pMapReg->uiRegister );

                /* Free the map register. */
                FreeMapReg( pAdapter, pDma->pMapReg );
                pDma->pMapReg = NULL;
            }

            /* This descriptor contains the last buffer in the packet. */
            if ( pDma->pNdisPacket )
            {
                /* Notify the network subsystem that the packet has been sent.
                */
                NdisMSendComplete( pAdapter->m_hAdapter, pDma->pNdisPacket,
                    NDIS_STATUS_SUCCESS );

                /* Release the packet back to network subsystem. */
                pDma->pNdisPacket = NULL;
            }

            /* Free the transmitted buffer. */
            Free_DMA_Buffer( &pAdapter->m_TxBufInfo, pDma );
            pDesc->pReserved = NULL;
        }

        /* Free the transmitted descriptor. */
        FreeTransmittedPacket( pInfo, iLast );
    }
    pInfo->iLast = iLast;

#ifdef SEND_QUEUE
    if ( pHardware->m_TxDescInfo.cnAvail >
            pHardware->m_TxDescInfo.cnAlloc / 4 )
        SendNextPacket( pAdapter );
#endif
}  // TransmitDone


/*
    TransmitReset

    Description:
        This routine resets the descriptors to starting state after a software
        reset.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

    Return (None):
*/

VOID TransmitReset (
    PNDIS_ADAPTER pAdapter )
{
    PHARDWARE   pHardware = &pAdapter->m_Hardware;
    PTDescInfo  pInfo = &pHardware->m_TxDescInfo;
    int         iLast;
    PTDesc      pDesc;
    PDMA_BUFFER pDma;
    TDescStat   status;

    iLast = pInfo->iLast;

    while ( pInfo->cnAvail < pInfo->cnAlloc )
    {
        /* Get next descriptor which is hardware owned. */
        GetTransmittedPacket( pInfo, iLast, pDesc, status.ulData );
        if ( status.tx.fHWOwned )
        {
            ReleaseDescriptor( pDesc, status );
        }

        pDma = DMA_BUFFER( pDesc );

        /* This descriptor contains a buffer. */
        if ( pDma )
        {
            /* It is a mapped buffer. */
            if ( pDma->pMapReg )
            {
                /* Ask network subsystem to free the mapping. */
                NdisMCompleteBufferPhysicalMapping(
                    pAdapter->m_hAdapter,
                    pDma->pMapReg->pNdisBuffer,
                    pDma->pMapReg->uiRegister );

                /* Free the map register. */
                FreeMapReg( pAdapter, pDma->pMapReg );
                pDma->pMapReg = NULL;
            }

            /* This descriptor contains the last buffer in the packet. */
            if ( pDma->pNdisPacket )
            {
                /* Notify the network subsystem that the packet has not been
                   sent.
                */
                NdisMSendComplete( pAdapter->m_hAdapter, pDma->pNdisPacket,
                    NDIS_STATUS_FAILURE );

                /* Release the packet back to network subsystem. */
                pDma->pNdisPacket = NULL;
            }

            /* Free the buffer. */
            Free_DMA_Buffer( &pAdapter->m_TxBufInfo, pDma );
            pDesc->pReserved = NULL;
        }

        /* Free the descriptor. */
        FreeTransmittedPacket( pInfo, iLast );
    }
    pInfo->iLast = iLast;
}  // TransmitReset

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

/*
    MiniportSend

    Description:
        This function sends one packet in NDIS 3.0.

    Parameters:
        PNDIS_ADAPTER pAdapter
            Pointer to adapter information structure.

        PNDIS_PACKET pPacket
            Pointer to NDIS packet.

        UINT uiFlags
            Send flags.

    Return (NDIS_STATUS):
        NDIS_STATUS_PENDING if successful; otherwise, an error code indicating
        failure.

⌨️ 快捷键说明

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