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

📄 interrup.c

📁 Realtek8139小端口网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        // a packet.
        //
        Adapter->BufferOverflow = FALSE;

        SyncCardAcknowledgeOverflow(Adapter);

        //
        // Undo loopback mode
        //
        CardStart(Adapter);

        IF_LOG( RTL8139Log('f'); )

        //
        // Check if transmission needs to be queued or not
        //
        if (Adapter->OverflowRestartXmitDpc && Adapter->CurBufXmitting != -1) {

            IF_LOUD( DbgPrint("queueing xmit in RcvDpc\n"); )

            Adapter->OverflowRestartXmitDpc = FALSE;

            Adapter->TransmitInterruptPending = TRUE;

            IF_LOG( RTL8139Log('5'); )

            CardStartXmit(Adapter);

        }
    }

    //
    // Finally, indicate ReceiveComplete to all protocols which received packets
    //
    if (Adapter->IndicateReceiveDone) {

        NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);

        Adapter->IndicateReceiveDone = FALSE;

    }

    IF_LOUD( DbgPrint( "RTL8139RcvDpc exiting\n" );)

    return (Done);

}


VOID
RTL8139XmitDpc(
    IN PRTL8139_ADAPTER Adapter
    )

/*++

Routine Description:

    This is the real interrupt handler for a transmit complete interrupt.
    RTL8139Dpc queues a call to it.

    Called after a transmit complete interrupt. It checks the
    status of the transmission, completes the send if needed,
    and sees if any more packets are ready to be sent.

Arguments:

    Adapter  - Pointer to the adapter block.

Return Value:

    None.

--*/

{
    //
    // Packet that was transmitted
    //
    PNDIS_PACKET Packet;

    //
    // Status of the send
    //
    NDIS_STATUS Status;

    //
    // Length of the packet sent
    //
    ULONG Len;

    //
    // Temporary loopnig variable
    //
    UINT i;

    IF_VERY_LOUD( DbgPrint( "RTL8139XmitDpc entered\n" );)

    //
    // Verify that we are transmitting a packet
    //
    if ( Adapter->CurBufXmitting == -1 ) {

#if DBG
        DbgPrint( "RTL8139HandleXmitComplete called with nothing transmitting!\n" );
#endif

        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_DRIVER_FAILURE,
            1,
            RTL8139_ERRMSG_HANDLE_XMIT_COMPLETE
            );

        return;
    }

    IF_LOG( RTL8139Log('C');)

    //
    // Get the status of the transmit
    //
    SyncCardGetXmitStatus((PVOID)Adapter);

    //
    // Statistics
    //
    if (Adapter->XmitStatus & TSR_XMIT_OK) {

        Adapter->FramesXmitGood++;
        Status = NDIS_STATUS_SUCCESS;

    } else {

        Adapter->FramesXmitBad++;
        Status = NDIS_STATUS_FAILURE;

    }

    //
    // Mark the current transmit as done.
    //
    Len = (Adapter->PacketLens[Adapter->CurBufXmitting] + 255) >> 8;

    ASSERT (Len != 0);

    //
    // Free the transmit buffers
    //
    for (i = Adapter->CurBufXmitting; i < Adapter->CurBufXmitting + Len; i++) {

        Adapter->BufferStatus[i] = EMPTY;

    }

    //
    // Set the next buffer to start transmitting.
    //
    Adapter->NextBufToXmit += Len;

    if (Adapter->NextBufToXmit == MAX_XMIT_BUFS) {

        Adapter->NextBufToXmit = 0;

    }

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

        Adapter->NextBufToXmit = 0;

    }

    //
    // Remove the packet from the outstanding packet list.
    //
    Packet = Adapter->Packets[Adapter->CurBufXmitting];
    Adapter->Packets[Adapter->CurBufXmitting] = (PNDIS_PACKET)NULL;

    //
    // See what to do next.
    //

    switch (Adapter->BufferStatus[Adapter->NextBufToXmit]) {


    case FULL:

        //
        // The next packet is ready to go -- only happens with
        // more than one transmit buffer.
        //

        IF_LOUD( DbgPrint( " next packet ready to go\n" );)

        //
        // Start the transmission and check for more.
        //

        Adapter->CurBufXmitting = Adapter->NextBufToXmit;

        IF_LOG( RTL8139Log('2');)

        //
        // This is used to check if stopping the chip prevented
        // a transmit complete interrupt from coming through (it
        // is cleared in the ISR if a transmit DPC is queued).
        //

        Adapter->TransmitInterruptPending = TRUE;

        IF_LOG( RTL8139Log('6'); )
        CardStartXmit(Adapter);

        break;

    case EMPTY:

        //
        // No packet is ready to transmit.
        //

        IF_LOUD( DbgPrint( " next packet empty\n" );)

        Adapter->CurBufXmitting = (XMIT_BUF)-1;

        break;

    }

    //
    // Start next send
    //

    RTL8139DoNextSend(Adapter);

    IF_VERY_LOUD( DbgPrint( "RTL8139XmitDpc exiting\n" );)

}


BOOLEAN
RTL8139PacketOK(
    IN PRTL8139_ADAPTER Adapter
    )

/*++

Routine Description:

    Reads a packet off the card -- checking if the CRC is good.  This is
    a workaround for a bug where bytes in the data portion of the packet
    are shifted either left or right by two in some weird 8390 cases.

    This routine is a combination of RTL8139TransferData (to copy up data
    from the card), CardCalculateCrc and CardCalculatePacketCrc.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE if the packet seems ok, else false.

--*/

{

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

    //
    // Guess at where the packet is located
    //
    PUCHAR PacketLoc;

    //
    // Header Validation Variables
    //
    BOOLEAN FrameAlign;
    PUCHAR PacketRcvStatus;
    PUCHAR NextPacket;
    PUCHAR PacketLenLo;
    PUCHAR PacketLenHi;
    PUCHAR ReceiveDestAddrLo;
    UINT FrameAlignCount;
    UCHAR OldPacketLenHi;
    UCHAR TempPacketHeader[6];
    PUCHAR BeginPacketHeader;

    //
    // First copy up the four-byte header the card attaches
    // plus first two bytes of the data packet (which contain
    // the destination address of the packet).  We use the extra
    // two bytes in case the packet was shifted right 1 or 2 bytes
    //
    PacketLoc = Adapter->PageStart +
        256*(Adapter->NicNextPacket-Adapter->NicPageStart);

    if (!CardCopyUp(Adapter, TempPacketHeader, PacketLoc, 6)) {

        return FALSE;

    }
    PacketLoc += 4;

    //
    // Validate the header
    //
    FrameAlignCount = 0;
    BeginPacketHeader = TempPacketHeader;

    //
    // Sometimes the RTL8139 will misplace a packet and shift the
    // entire packet and header by a byte, either up by 1 or 2 bytes.
    // This loop will look for the packet in the expected place,
    // and then shift up in an effort to find the packet.
    //
    do {

        //
        // Set where we think the packet is
        //
        PacketRcvStatus = BeginPacketHeader;
        NextPacket = BeginPacketHeader + 1;
        PacketLenLo = BeginPacketHeader + 2;
        PacketLenHi = BeginPacketHeader + 3;
        OldPacketLenHi = *PacketLenHi;
        ReceiveDestAddrLo = BeginPacketHeader + 4;
        FrameAlign = FALSE;

        //
        // Check if the status makes sense as is.
        //
        if (*PacketRcvStatus & 0x05E){

            FrameAlign = TRUE;

        } else if ((*PacketRcvStatus & RSR_MULTICAST)   // If a multicast packet
                     && (!FrameAlignCount)              // and hasn't been aligned
                     && !(*ReceiveDestAddrLo & 1)       // and lsb is set on dest addr
                  ){

            FrameAlign = TRUE;

        } else {

            //
            // Compare high and low address bytes.  If the same, the low
            // byte may have been copied into the high byte.
            //

            if (*PacketLenLo == *PacketLenHi){

                //
                // Save the old packetlenhi
                //
                OldPacketLenHi = *PacketLenHi;

                //
                // Compute new packet length
                //
                *PacketLenHi = *NextPacket - Adapter->NicNextPacket - 1;

                if (*PacketLenHi < 0) {

                    *PacketLenHi = (Adapter->NicPageStop - Adapter->NicNextPacket) +
                        (*NextPacket - Adapter->NicPageStart) - 1;

                }

                if (*PacketLenLo > 0xFC) {

                    *PacketLenHi++;
                }

            }

            PacketLen = (*PacketLenLo) + ((*PacketLenHi)*256) - 4;

            //
            // Does it make sense?
            //
            if ((PacketLen > 1514) || (PacketLen < 60)){

                //
                // Bad length.  Restore the old packetlenhi
                //
                *PacketLenHi = OldPacketLenHi;

                FrameAlign = TRUE;

            }

            //
            // Did we recover the frame?
            //
            if (!FrameAlign && ((*NextPacket < Adapter->NicPageStart) ||
                (*NextPacket > Adapter->NicPageStop))) {

                IF_LOUD( DbgPrint ("Packet address invalid in HeaderValidation\n"); )

                FrameAlign = TRUE;

            }

        }

        //
        // FrameAlignment - if first time through, shift packetheader right 1 or 2 bytes.
        // If second time through, shift it back to where it was and let it through.
        // This compensates for a known bug in the 8390D chip.
        //
        if (FrameAlign){

            switch (FrameAlignCount){

            case 0:

                BeginPacketHeader++;
                PacketLoc++;
                if (!Adapter->EightBitSlot){

                    BeginPacketHeader++;
                    PacketLoc++;

                }
                break;

            case 1:

                BeginPacketHeader--;
                PacketLoc--;
                if (!Adapter->EightBitSlot){
                    BeginPacketHeader--;
                    PacketLoc--;
                }
                break;

            }

            FrameAlignCount++;

        }

    } while ( (FrameAlignCount < 2) && FrameAlign );

    //
    // Now grab the packet header information
    //
    Adapter->PacketHeader[0] = *BeginPacketHeader;
    BeginPacketHeader++;
    Adapter->PacketHeader[1] = *BeginPacketHeader;
    BeginPacketHeader++;
    Adapter->PacketHeader[2] = *BeginPacketHeader;
    BeginPacketHeader++;
    Adapter->PacketHeader[3] = *BeginPacketHeader;

    //
    // Packet length is in bytes 3 and 4 of the header.
    //
    Adapter->PacketHeaderLoc = PacketLoc;
    PacketLen = (Adapter->PacketHeader[2]) + ((Adapter->PacketHeader[3])*256) - 4;

    //
    // Sanity check the packet
    //
    if ((PacketLen > 1514) || (PacketLen < 60)){

        if ((Adapter->PacketHeader[1] < Adapter->NicPageStart) ||
            (Adapter->PacketHeader[1] > Adapter->NicPageStop)) {

            //
            // Return TRUE here since IndicatePacket will notice the error
            // and handle it correctly.
            //
            return(TRUE);

        }

        return(FALSE);

⌨️ 快捷键说明

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