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

📄 interrup.c

📁 Realtek8139小端口网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    }

    return(TRUE);
}


INDICATE_STATUS
RTL8139IndicatePacket(
    IN PRTL8139_ADAPTER Adapter
    )

/*++

Routine Description:

    Indicates the first packet on the card to the protocols.

    NOTE: For MP, non-x86 architectures, this assumes that the packet has been
    read from the card and into Adapter->PacketHeader and Adapter->Lookahead.

    NOTE: For UP x86 systems this assumes that the packet header has been
    read into Adapter->PacketHeader and the minimal lookahead stored in
    Adapter->Lookahead

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    CARD_BAD if the card should be reset;
    INDICATE_OK otherwise.

--*/

{
    //
    // Length of the packet
    //
    UINT PacketLen;

    //
    // Length of the lookahead buffer
    //
    UINT IndicateLen;

    //
    // Variables for checking if the packet header looks valid
    //
    UCHAR PossibleNextPacket1, PossibleNextPacket2;

    //
    // Check if the next packet byte agress with the length, as
    // described on p. A-3 of the Etherlink II Technical Reference.
    // The start of the packet plus the MSB of the length must
    // be equal to the start of the next packet minus one or two.
    // Otherwise the header is considered corrupted, and the
    // card must be reset.
    //

    PossibleNextPacket1 =
                Adapter->NicNextPacket + Adapter->PacketHeader[3] + (UCHAR)1;

    if (PossibleNextPacket1 >= Adapter->NicPageStop) {

        PossibleNextPacket1 -= (Adapter->NicPageStop - Adapter->NicPageStart);

    }

    if (PossibleNextPacket1 != Adapter->PacketHeader[1]) {

        PossibleNextPacket2 = PossibleNextPacket1+(UCHAR)1;

        if (PossibleNextPacket2 == Adapter->NicPageStop) {

            PossibleNextPacket2 = Adapter->NicPageStart;

        }

        if (PossibleNextPacket2 != Adapter->PacketHeader[1]) {

            IF_LOUD( DbgPrint("First CARD_BAD check failed\n"); )
            return SKIPPED;
        }

    }

    //
    // Check that the Next is valid
    //
    if ((Adapter->PacketHeader[1] < Adapter->NicPageStart) ||
        (Adapter->PacketHeader[1] > Adapter->NicPageStop)) {

        IF_LOUD( DbgPrint("Second CARD_BAD check failed\n"); )
        return(SKIPPED);

    }

    //
    // Sanity check the length
    //
    PacketLen = Adapter->PacketHeader[2] + Adapter->PacketHeader[3]*256 - 4;

    if (PacketLen > 1514) {
        IF_LOUD( DbgPrint("Third CARD_BAD check failed\n"); )
        return(SKIPPED);

    }

#if DBG

    IF_RTL8139DEBUG( RTL8139_DEBUG_WORKAROUND1 ) {
        //
        // Now check for the high order 2 bits being set, as described
        // on page A-2 of the Etherlink II Technical Reference. If either
        // of the two high order bits is set in the receive status byte
        // in the packet header, the packet should be skipped (but
        // the adapter does not need to be reset).
        //

        if (Adapter->PacketHeader[0] & (RSR_DISABLED|RSR_DEFERRING)) {

            IF_LOUD (DbgPrint("H");)

            return SKIPPED;

        }

    }

#endif

    //
    // Lookahead amount to indicate
    //
    IndicateLen = (PacketLen > (Adapter->MaxLookAhead + RTL8139_HEADER_SIZE)) ?
                           (Adapter->MaxLookAhead + RTL8139_HEADER_SIZE) :
                           PacketLen;

    //
    // Indicate packet
    //

    Adapter->PacketLen = PacketLen;

    if (IndicateLen < RTL8139_HEADER_SIZE) {

        //
        // Runt Packet
        //

        NdisMEthIndicateReceive(
                Adapter->MiniportAdapterHandle,
                (NDIS_HANDLE)Adapter,
                (PCHAR)(Adapter->Lookahead),
                IndicateLen,
                NULL,
                0,
                0
                );

    } else {

        NdisMEthIndicateReceive(
                Adapter->MiniportAdapterHandle,
                (NDIS_HANDLE)Adapter,
                (PCHAR)(Adapter->Lookahead),
                RTL8139_HEADER_SIZE,
                (PCHAR)(Adapter->Lookahead) + RTL8139_HEADER_SIZE,
                IndicateLen - RTL8139_HEADER_SIZE,
                PacketLen - RTL8139_HEADER_SIZE
                );

    }

    Adapter->IndicateReceiveDone = TRUE;

    return INDICATE_OK;
}


NDIS_STATUS
RTL8139TransferData(
    OUT PNDIS_PACKET Packet,
    OUT PUINT BytesTransferred,
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_HANDLE MiniportReceiveContext,
    IN UINT ByteOffset,
    IN UINT BytesToTransfer
    )

/*++

Routine Description:

    A protocol calls the RTL8139TransferData 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.
    //
    XMIT_BUF NextBufToXmit;
    PUCHAR BufStart;

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

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

    IF_LOG( RTL8139Log('t');)

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

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

        if (Adapter->PacketLen < ByteOffset) {

            *BytesTransferred = 0;
            IF_LOG( RTL8139Log('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 -- it is not completely stored in the
        // adapter structure.
        //
        // Determine where the copying should start.
        //
        CurCardLoc = Adapter->PacketHeaderLoc + ByteOffset;

        if (CurCardLoc > Adapter->PageStop) {

            CurCardLoc = CurCardLoc - (Adapter->PageStop - Adapter->PageStart);

        }

        //
        // 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);

            }

            //
            // See if the data for this buffer wraps around the end
            // of the receive buffers (if so filling this buffer
            // will use two iterations of the loop).
            //

            if (CurCardLoc + BytesNow > Adapter->PageStop) {

                BytesNow = (UINT)(Adapter->PageStop - CurCardLoc);

            }

            //
            // Copy up the data.
            //

            if (!CardCopyUp(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;

            }

            //
            // Wrap around the end of the receive buffers?
            //
            if (CurCardLoc == Adapter->PageStop) {

                CurCardLoc = Adapter->PageStart;

            }

            //
            // 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;

        //
        // Did a transmit complete while we were doing what we were doing?
        //
        if (!Adapter->BufferOverflow && Adapter->CurBufXmitting != -1) {

            ULONG Len;
            UINT i;
            UCHAR Status;
            PNDIS_PACKET Packet;
            NDIS_STATUS NdisStatus;

            //
            // Check if it completed
            //
            CardGetInterruptStatus(Adapter, &Status);

            if (Status & ISR_XMIT_ERR) {
                OctogmetusceratorRevisited(Adapter);
                Adapter->InterruptStatus &= ~ISR_XMIT_ERR;
                NdisRawWritePortUchar(Adapter->IoAddr+NIC_INTR_STATUS, (ISR_XMIT_ERR));
                Status &= ~ISR_XMIT_ERR;

            }

            if (Status & (ISR_XMIT)) {


                IF_LOG( RTL8139Log('*'); )


                //
                // Update NextBufToXmit
                //
                Len = (Adapter->PacketLens[Adapter->CurBufXmitting] + 255) >> 8;
                NextBufToXmit = Adapter->NextBufToXmit + Len;

//                Adapter->NextBufToXmit += Len;

                if (NextBufToXmit == MAX_XMIT_BUFS) {
                    NextBufToXmit = 0;
                }

                if (Adapter->BufferStatus[NextBufToXmit] == EMPTY &&
                    Adapter->NextBufToFill != NextBufToXmit) {
                    NextBufToXmit = 0;
                }


                //
                // If the next packet is ready to go, start it.
                //
                if (Adapter->BufferStatus[NextBufToXmit] == FULL) {

                    //
                    // Ack the transmit
                    //

                    //
                    // Remove the packet from the packet list.
                    //
                    Adapter->NextBufToXmit = NextBufToXmit;

⌨️ 快捷键说明

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