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

📄 card.c

📁 Realtek8139小端口网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
        NdisRawWritePortUchar(
            Adapter->IoAddr + NIC_DATA_CONFIG,
            DCR_FIFO_8_BYTE | DCR_NORMAL | DCR_WORD_WIDE
        );
    }

    //
    // Clear transmit configuration.
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_CONFIG, 0);

    //
    // Clear receive configuration.
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RCV_CONFIG, 0);

    //
    // Clear any interrupts
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_STATUS, 0xFF);

    //
    // Stop the chip
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_NO_DMA | CR_STOP);

    //
    // Clear any DMA values
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0);

    //
    // Clear any DMA values
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0);

    //
    // Wait for the reset to complete.
    //
    i = 0x3FFF;

    while (--i)
    {
        NdisRawReadPortUchar(Adapter->IoAddr + NIC_INTR_STATUS, &Tmp);

        if (Tmp & ISR_RESET)
            break;

        NdisStallExecution(4);
    }

    //
    // Put card in loopback mode
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_CONFIG, TCR_LOOPBACK);

    //
    // Start the chip.
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        CR_NO_DMA | CR_START
    );

    //
    // Test for the amount of RAM
    //
    CardRamTest(Adapter);


    //
    // Stop the chip
    //
    SyncCardStop(Adapter);

    return(TRUE);
}


#pragma NDIS_PAGEABLE_FUNCTION(CardReadEthernetAddress)

BOOLEAN CardReadEthernetAddress(
    IN PRTL8139_ADAPTER Adapter
)

/*++

Routine Description:

    Reads in the Ethernet address from the Novell 2000.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    The address is stored in Adapter->PermanentAddress, and StationAddress if it
    is currently zero.

--*/

{
    UINT    c;

    //
    //  Things are done a little differently for PCMCIA adapters.
    //




	

  
        //
        // Setup to read the ethernet address
        //
        NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 12);
        NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0);
        NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_LSB, 0);
        NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_MSB, 0);
        NdisRawWritePortUchar(
            Adapter->IoAddr + NIC_COMMAND,
            CR_START | CR_DMA_READ | CR_PAGE1
        );

        //
        // Read in the station address. (We have to read words -- 2 * 6 -- bytes)
        //
        for (c = 0; c < RTL8139_LENGTH_OF_ADDRESS; c++)
        {
            NdisRawReadPortUchar(
                Adapter->IoAddr + NIC_PHYS_ADDR+c,
                &Adapter->PermanentAddress[c]
            );
        }

    IF_LOUD(
        DbgPrint(
            "RTL8139: PermanentAddress [ %02x-%02x-%02x-%02x-%02x-%02x ]\n",
            Adapter->PermanentAddress[0],
            Adapter->PermanentAddress[1],
            Adapter->PermanentAddress[2],
            Adapter->PermanentAddress[3],
            Adapter->PermanentAddress[4],
            Adapter->PermanentAddress[5]
        );
    )

    //
    // Use the burned in address as the station address, unless the
    // registry specified an override value.
    //
    if ((Adapter->StationAddress[0] == 0x00) &&
        (Adapter->StationAddress[1] == 0x00) &&
        (Adapter->StationAddress[2] == 0x00) &&
        (Adapter->StationAddress[3] == 0x00) &&
        (Adapter->StationAddress[4] == 0x00) &&
        (Adapter->StationAddress[5] == 0x00)
    )
    {
        Adapter->StationAddress[0] = Adapter->PermanentAddress[0];
        Adapter->StationAddress[1] = Adapter->PermanentAddress[1];
        Adapter->StationAddress[2] = Adapter->PermanentAddress[2];
        Adapter->StationAddress[3] = Adapter->PermanentAddress[3];
        Adapter->StationAddress[4] = Adapter->PermanentAddress[4];
        Adapter->StationAddress[5] = Adapter->PermanentAddress[5];
    }

    return(TRUE);
}


BOOLEAN
CardSetup(
    IN PRTL8139_ADAPTER Adapter
    )

/*++

Routine Description:

    Sets up the card.

Arguments:

    Adapter - pointer to the adapter block, which must be initialized.

Return Value:

    TRUE if successful.

--*/

{
    UINT i;
    UINT Filter;
    UCHAR Tmp;


    //
    // Write to and read from CR to make sure it is there.
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        CR_STOP | CR_NO_DMA | CR_PAGE0
    );

    NdisRawReadPortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        &Tmp
    );
    if ((Tmp & (CR_STOP | CR_NO_DMA | CR_PAGE0)) !=
        (CR_STOP | CR_NO_DMA | CR_PAGE0)
    )
    {
        return(FALSE);
    }

    //
    // Set up the registers in the correct sequence, as defined by
    // the 8390 specification.
    //
    if (Adapter->EightBitSlot)
    {
        NdisRawWritePortUchar(
            Adapter->IoAddr + NIC_DATA_CONFIG,
            DCR_BYTE_WIDE | DCR_NORMAL | DCR_FIFO_8_BYTE
        );
    }
    else
    {
        NdisRawWritePortUchar(
            Adapter->IoAddr + NIC_DATA_CONFIG,
            DCR_WORD_WIDE | DCR_NORMAL | DCR_FIFO_8_BYTE
        );
    }


    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0);

    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0);

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_RCV_CONFIG,
        Adapter->NicReceiveConfig
    );

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_XMIT_CONFIG,
        TCR_LOOPBACK
    );

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_BOUNDARY,
        Adapter->NicPageStart
    );

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_PAGE_START,
        Adapter->NicPageStart
    );

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_PAGE_STOP,
        Adapter->NicPageStop
    );

    Adapter->Current = Adapter->NicPageStart + (UCHAR)1;
    Adapter->NicNextPacket = Adapter->NicPageStart + (UCHAR)1;
    Adapter->BufferOverflow = FALSE;

    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_STATUS, 0xff);

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_INTR_MASK,
        Adapter->NicInterruptMask
    );


    //
    // Move to page 1 to write the station address
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        CR_STOP | CR_NO_DMA | CR_PAGE1
    );

    for (i = 0; i < RTL8139_LENGTH_OF_ADDRESS; i++)
    {
        NdisRawWritePortUchar(
            Adapter->IoAddr + (NIC_PHYS_ADDR + i),
            Adapter->StationAddress[i]
        );
    }

    Filter = Adapter->PacketFilter;

    //
    // Write out the multicast addresses
    //
    for (i = 0; i < 8; i++)
    {
        NdisRawWritePortUchar(
            Adapter->IoAddr + (NIC_MC_ADDR + i),
            (UCHAR)((Filter & NDIS_PACKET_TYPE_ALL_MULTICAST) ?
                    0xff : Adapter->NicMulticastRegs[i])
        );
    }

    //
    // Write out the current receive buffer to receive into
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_CURRENT,
        Adapter->Current
    );


    //
    // move back to page 0 and start the card...
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        CR_STOP | CR_NO_DMA | CR_PAGE0
    );

    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        CR_START | CR_NO_DMA | CR_PAGE0
    );

    //
    // ... but it is still in loopback mode.
    //
    return(TRUE);
}

VOID CardStop(
    IN PRTL8139_ADAPTER Adapter
)

/*++

Routine Description:

    Stops the card.

Arguments:

    Adapter - pointer to the adapter block

Return Value:

    None.

--*/

{
    UINT i;
    UCHAR Tmp;

    //
    // Turn on the STOP bit in the Command register.
    //
    SyncCardStop(Adapter);

    //
    // Clear the Remote Byte Count register so that ISR_RESET
    // will come on.
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_MSB, 0);
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 0);


    //
    // Wait for ISR_RESET, but only for 1.6 milliseconds (as
    // described in the March 1991 8390 addendum), since that
    // is the maximum time for a software reset to occur.
    //
    //
    for (i = 0; i < 4; i++)
    {
        NdisRawReadPortUchar(Adapter->IoAddr+NIC_INTR_STATUS, &Tmp);
        if (Tmp & ISR_RESET)
            break;

        NdisStallExecution(500);
    }

    if (i == 4)
    {
        IF_LOUD( DbgPrint("RESET\n");)
        IF_LOG( RTL8139Log('R');)
    }

    //
    // Put the card in loopback mode, then start it.
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_CONFIG, TCR_LOOPBACK);
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_START | CR_NO_DMA);

    //
    // At this point the card is still in loopback mode.
    //
}

BOOLEAN CardReset(
    IN PRTL8139_ADAPTER Adapter
)

/*++

Routine Description:

    Resets the card.

Arguments:

    Adapter - pointer to the adapter block

Return Value:

    TRUE if everything is OK.

--*/

{
    //
    // Stop the chip
    //
    CardStop(Adapter);

    //
    // Wait for the card to finish any receives or transmits
    //
    NdisStallExecution(2000);

    //
    // CardSetup() does a software reset.
    //
    if (!CardSetup(Adapter))
    {
        NdisWriteErrorLogEntry(
            Adapter->MiniportAdapterHandle,
            NDIS_ERROR_CODE_HARDWARE_FAILURE,
            2,
            cardReset,
            RTL8139_ERRMSG_CARD_SETUP
        );

        return(FALSE);
    }

    //
    // Restart the chip
    //
    CardStart(Adapter);

    return TRUE;
}



BOOLEAN CardCopyDownPacket(
    IN PRTL8139_ADAPTER  Adapter,
    IN PNDIS_PACKET     Packet,
    OUT PUINT           Length
)

/*++

Routine Description:

    Copies the packet Packet down starting at the beginning of
    transmit buffer XmitBufferNum, fills in Length to be the
    length of the packet.

Arguments:

    Adapter - pointer to the adapter block
    Packet - the packet to copy down

Return Value:

    Length - the length of the data in the packet in bytes.
    TRUE if the transfer completed with no problems.

--*/

{
    //
    // Addresses of the Buffers to copy from and to.
    //
    PUCHAR CurBufAddress;
    PUCHAR OddBufAddress;
    PUCHAR XmitBufAddress;

    //
    // Length of each of the above buffers
    //
    UINT CurBufLen;
    UINT PacketLength;

    //
    // Was the last transfer of an odd length?
    //
    BOOLEAN OddBufLen = FALSE;

    //
    // Current NDIS_BUFFER that is being copied from
    //
    PNDIS_BUFFER CurBuffer;

    //
    // Programmed I/O, have to transfer the data.
    //
    NdisQueryPacket(Packet, NULL, NULL, &CurBuffer, &PacketLength);

    //
    // Skip 0 length copies
    //
    if (PacketLength == 0) {
        return(TRUE);
    }

    //
    // Get the starting buffer address
    //
    XmitBufAddress = (PUCHAR)Adapter->XmitStart +
                    Adapter->NextBufToFill*TX_BUF_SIZE;

    //
    // Get address and length of the first buffer in the packet
    //
    NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);

    while (CurBuffer && (CurBufLen == 0)) {

        NdisGetNextBuffer(CurBuffer, &CurBuffer);

        NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);

    }

    //
    // set up the card
    //
    {

        //
        // Temporary places for holding values for transferring to
        // an odd aligned address on 16-bit slots.
        //
        UCHAR Tmp;
        UCHAR Tmp1;
        USHORT TmpShort;

        //
        // Values for waiting for noticing when a DMA completes.
        //
        USHORT OldAddr, NewAddr;

        //
        // Count of transfers to do
        //
        USHORT Count;

        //
        // Buffer to read from for odd aligned transfers
        //
        PUCHAR ReadBuffer;

        if (!Adapter->EightBitSlot && ((ULONG_PTR)XmitBufAddress & 0x1)) {

            //
            // Avoid transfers to odd addresses in word mode.
            //
            // For odd addresses we need to read first to get the previous
            // byte and then merge it with our first byte.
            //

            //
            // Set Count and Source address
            //

//          NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_PAGE0);  // robin

⌨️ 快捷键说明

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