intcom.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,163 行 · 第 1/3 页

C
1,163
字号
        PacketLen -= ETH_CRC_SIZE;  /* Strip off the 4-byte CRC field. */
    }

    /* Indicate the packet to the wrapper. */
    Adapter->PacketLen = PacketLen;

    /* Note: NdisMEthIndicateReceive() also transfers the data. */
    if (PacketLen < ETH_HEADER_SIZE)
    {
    /* Runt Packet. */
    NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle,
                (NDIS_HANDLE)Adapter,
                Adapter->ActiveRx.pBuffer,
                PacketLen,
                NULL,
                0,
                0);

    } else {

    /* OK to set the lookahead buffer size equal to the complete frame. */
        NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle,
                            (NDIS_HANDLE)Adapter,
                Adapter->ActiveRx.pBuffer,
                ETH_HEADER_SIZE,
                Adapter->ActiveRx.pBuffer + ETH_HEADER_SIZE,
                PacketLen - ETH_HEADER_SIZE,
                PacketLen - ETH_HEADER_SIZE);

    Adapter->FramesRcvGood++;
    }

    DEBUGMSG(ZONE_FUNCTION | ZONE_RCV,
    (TEXT("-ETH8XX: eth8xxIndicatePacket\r\n")));
}


/*----------------------------------------------------------------------*/
NDIS_STATUS eth8xxTransferData(OUT PNDIS_PACKET Packet,
                   OUT PUINT        BytesTransferred,
                               IN  NDIS_HANDLE  MiniportAdapterContext,
                               IN  NDIS_HANDLE  MiniportReceiveContext,
                   IN  UINT         ByteOffset,
                   IN  UINT         BytesToTransfer)

/*++
Description:

    A protocol calls the eth8xxTransferData request (indirectly via
    NdisTransferData) from within its Receive event handler to
    instruct the driver to copy the contents of the received packet
    a specified packet buffer.

Arguments:

    MiniportAdapterContext - Context registered with the wrapper, really
                 a pointer to the adapter.

    MiniportReceiveContext - The context value passed by the driver on
                 its call to NdisMEthIndicateReceive. The
                 driver can use this value to determine
                             which packet, on which adapter, is being
                 received.

    ByteOffset - An unsigned integer specifying the offset within the
                 received packet at which the copy is to begin.  If the
         entire packet is to be copied, ByteOffset must be zero.

    BytesToTransfer - An unsigned integer specifying the number of bytes
              to copy.  It is legal to transfer zero bytes; this
              has no effect.  If the sum of ByteOffset and
              BytesToTransfer is greater than the size of the
              received packet, then the remainder of the packet
              (starting from ByteOffset) is transferred, and the
              trailing portion of the receive buffer is not modified.

    Packet - A pointer to a descriptor for the packet storage into which
         the MAC is to copy the received packet.

    BytesTransfered - A pointer to an unsigned integer.  The MAC writes
              the actual number of bytes transferred into this
              location.  This value is not valid if the return
              status is STATUS_PENDING.

Notes:

  - The MacReceiveContext will be a pointer to the open block for
    the packet.

--*/

{
    /* Variables for the number of bytes to copy, how much can be
     * copied at this moment, and the total number of bytes to copy.
     */
    UINT BytesLeft, BytesNow, BytesWanted;

    /* Current NDIS_BUFFER to copy into */
    PNDIS_BUFFER CurBuffer;

    /* Virtual address of the buffer. */
    PUCHAR BufStart;

    /* Length and offset into the buffer. */
    UINT BufLen, BufOff;

    /* The adapter to transfer from. */
    PETH8XX_ADAPTER Adapter = ((PETH8XX_ADAPTER)MiniportReceiveContext);

    DEBUGMSG(ZONE_FUNCTION | ZONE_RCV,
    (TEXT("+ETH8XX: eth8xxTransferData\r\n")));

    IF_LOG( eth8xxLog('t');)

    /* Add the packet header onto the offset. */
    ByteOffset += ETH_HEADER_SIZE;

    /* See how much data there is to transfer. */
    if (ByteOffset+BytesToTransfer > Adapter->PacketLen) {

        if (Adapter->PacketLen < ByteOffset) {

            *BytesTransferred = 0;
            IF_LOG( eth8xxLog('T');)
            return(NDIS_STATUS_FAILURE);
        }

        BytesWanted = Adapter->PacketLen - ByteOffset;

    } else {

        BytesWanted = BytesToTransfer;

    }

    /* Set the number of bytes left to transfer. */
    BytesLeft = BytesWanted;

    {

        /* Address on the adapter to copy from. */
        PUCHAR CurCardLoc;

        /* Copy data from the card.
         *
         * Determine where the copying should start.
         */
        CurCardLoc = Adapter->ActiveRx.pBuffer + ByteOffset;

        /* Get location to copy into. */
        NdisQueryPacket(Packet, NULL, NULL, &CurBuffer, NULL);

        NdisQueryBuffer(CurBuffer, (PVOID *)&BufStart, &BufLen);

        BufOff = 0;

        /* Loop, filling each buffer in the packet until there
         * are no more buffers or the data has all been copied.
         */
        while (BytesLeft > 0) {

            /* See how much data to read into this buffer. */

            if ((BufLen-BufOff) > BytesLeft) {

                BytesNow = BytesLeft;

            } else {

                BytesNow = (BufLen - BufOff);

            }

            /* Copy up the data. */

            if (!HW_Copy_Up_Packet(Adapter, BufStart+BufOff, CurCardLoc,
                   BytesNow))
        {

        *BytesTransferred = BytesWanted - BytesLeft;

                NdisWriteErrorLogEntry(
                    Adapter->MiniportAdapterHandle,
                    NDIS_ERROR_CODE_HARDWARE_FAILURE,
                    1,
                    0x2
                    );

                return(NDIS_STATUS_FAILURE);

            }

            /* Update offsets and counts. */
            CurCardLoc += BytesNow;
            BytesLeft -= BytesNow;

            /* Is the transfer done now? */
            if (BytesLeft == 0) {

                break;

            }

            /* Was the end of this packet buffer reached? */
            BufOff += BytesNow;

            if (BufOff == BufLen) {

                NdisGetNextBuffer(CurBuffer, &CurBuffer);

                if (CurBuffer == (PNDIS_BUFFER)NULL) {

                    break;

                }

                NdisQueryBuffer(CurBuffer, (PVOID *)&BufStart, &BufLen);

                BufOff = 0;

            }

        }

        *BytesTransferred = BytesWanted - BytesLeft;

    DEBUGMSG(ZONE_FUNCTION | ZONE_RCV,
        (TEXT("-ETH8XX: eth8xxTransferData\r\n")));

        return(NDIS_STATUS_SUCCESS);
    }
}


/*----------------------------------------------------------------------*/
NDIS_STATUS eth8xxDoNextSend(PETH8XX_ADAPTER Adapter, BOOLEAN inXmitDpc)
/*++

Description:

    This routine checks if there is there are additional packets
    waiting to be transmitted. If there are, copy as many down to
    the adapter as possible.

Arguments:

    Adapter - Pointer to the miniport adapter block.

Return Value:

    None

--*/
{
    PNDIS_PACKET Packet;      /* Next NDIS buffer-chain (packet) to tx. */
    ULONG        Len;         /* Length in bytes of the NDIS packet.    */
    UINT     count = 0;   /* Avoid starving rest of system.         */
    NDIS_STATUS  sendStatus = NDIS_STATUS_PENDING;

    DEBUGMSG(ZONE_FUNCTION | ZONE_XMIT,
    (TEXT("+ETH8XX: eth8xxDoNextSend\r\n")));

    IF_LOG( eth8xxLog('S'); )
    IF_LOG( eth8xxLog('S'); )

    /* If we're shutting down, then just get out of here. */
    if (Adapter->Status != ENABLED)
    {
    DEBUGMSG(ZONE_XMIT | ZONE_WARN,
        (TEXT(" ETH8XX: Send aborted, interface not enabled.\r\n")));
    return(NDIS_STATUS_FAILURE);

    }

    while (count < ETH_MAX_LOOP_ITERATIONS)
    {
    count++;    /* limit loop to 10 iterations per call */

    EnterCriticalSection(&v_UpdateTxBufList);

    if (Adapter->FirstPacket == NULL)
    {
        /* Transmit queue is empty, nothing to do. */
        LeaveCriticalSection(&v_UpdateTxBufList);
        break;

    } else if (Adapter->FreeTx.pBufferDescriptor == NULL) {

        /* No available buffer descriptors, try again later. Note that
         * the packet has been queued but not assigned to a transmit
         * buffer.
         */
        if (!inXmitDpc)
        {
        /* Tell NDIS that packet will be transmitted later. */
        sendStatus = NDIS_STATUS_PENDING;
        }

        LeaveCriticalSection(&v_UpdateTxBufList);
        break;

    }

    /* Remove the packet from the queue. */
    Packet = Adapter->FirstPacket;
    Adapter->FirstPacket = RESERVED(Packet)->Next;
    if (Packet == Adapter->LastPacket)
    {
        Adapter->LastPacket = NULL;
    }
      
    /* Get the length of the NDIS packet. */
    NdisQueryPacket(Packet, NULL, NULL, NULL, &Len);

    if (Len == 0)
    {
        /* Acknowledge but no need to transmit zero-length packets. */
        sendStatus = NDIS_STATUS_SUCCESS;

    } else if (HW_Copy_Down_Packet(Adapter, Packet, &(Adapter->FreeTx))) {
  
        IF_LOG(eth8xxLog('j');) 
        IF_LOG(eth8xxLog('j');) 

        /* Tell transmitter that frame is now ready to go. */
        HW_Start_Xmit(Adapter, &(Adapter->FreeTx));

        /* Update the active buffer list. */
        if (Adapter->ActiveTx.pBufferDescriptor == NULL)
        {
        /* Insert first active buffer into list. */
        Adapter->ActiveTx.pBufferDescriptor =
            Adapter->FreeTx.pBufferDescriptor;
        Adapter->ActiveTx.pBuffer = Adapter->FreeTx.pBuffer;
        }
  
        /* Update the free buffer list. */
        HW_Advance_Element(&(Adapter->FreeTx),
                   0xFF,
                   0x00,
                   Adapter->FirstTxBD,
                   Adapter->TxStart,
                   Adapter->LastTxBD,
                   Adapter->MaxTxBufferSize,
                   FALSE);

        if (Adapter->FreeTx.pBufferDescriptor ==
        Adapter->ActiveTx.pBufferDescriptor)
        {
        DEBUGMSG(ZONE_XMIT | ZONE_WARN,
            (TEXT(" ETH8XX: used up all free Tx buffers\r\n")));

        /* No more free buffers. */
        Adapter->FreeTx.pBufferDescriptor = NULL;
        Adapter->FreeTx.pBuffer           = NULL;
        }

        sendStatus = NDIS_STATUS_SUCCESS;

    } else {

        IF_LOG( eth8xxLog('F'); )
        IF_LOG( eth8xxLog('S'); )

        sendStatus = NDIS_STATUS_FAILURE;
    }

    LeaveCriticalSection(&v_UpdateTxBufList);
      
    if (inXmitDpc)
    {
        /* Acknowledge an earlier eth8xxSend() request. */
        NdisMSendComplete(Adapter->MiniportAdapterHandle,
                  Packet,
                  sendStatus);
    }
    }

    IF_LOG(eth8xxLog('s');) 
    IF_LOG(eth8xxLog('s');) 

    DEBUGMSG(ZONE_FUNCTION | ZONE_XMIT,
    (TEXT("-ETH8XX: eth8xxDoNextSend\r\n")));

    return(sendStatus);
}

⌨️ 快捷键说明

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