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

📄 card.c

📁 Realtek8139小端口网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
2004.12  第十项目小组 
主编:王翔 徐隽
协助:卢坚 夏亮 傅佳伟  郑皓 黄君炜
测试:王弥 
Rtl8139 根据 Win2000 DDK提供的Network Samples框架基础上进行编码                                           
 
  (声明:本驱动程序仅用于学习、探索、实践计算机网络相关知识之用。
请勿在未征得本小组同意的情况下随意传播。对使用本程序可能造成的
硬件问题本小组概不负责。也请勿将它用于学习之外的任何用途,本小组
对此种行为可能造成的不良后果概不负责。)                                          
           
****************************************************************************/

/****************************************************************************
模块名称:
    card.c

模块功能:
	此模块定义硬件特定功能函数,供注册函数调用,
	结构上沿用Win2000 DDK提供的Network Samples提供的card.c文件

开发环境:
    WinDDK XP 
	Visual C++6.0
    Driver Studio 3.1
*****************************************************************************/


#define	NDIS_WDM 1
#define NDIS_MINIPORT_DRIVER
#define NDIS50_MINIPORT   1 //NDIS版本5.0
#include "ndis.h"
#include "RTL8139sw.h"
#include "RTL8139hw.h"

BOOLEAN
CardSlotTest(
    IN PRTL8139_ADAPTER Adapter
    );

BOOLEAN
CardRamTest(
    IN PRTL8139_ADAPTER Adapter
    );


#pragma NDIS_PAGEABLE_FUNCTION(CardCheckParameters)

BOOLEAN CardCheckParameters(
    IN PRTL8139_ADAPTER Adapter
)

/*++

Routine Description:

    Checks that the I/O base address is correct.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if IoBaseAddress appears correct.

--*/

{
    UCHAR Tmp;

    //
    // If adapter responds to a stop command correctly -- assume it is there.
    //

    //
    // Turn off interrupts first.
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_MASK, 0);

    //
    // Stop the card.
    //
    SyncCardStop(Adapter);

    //
    // Pause
    //
    NdisStallExecution(2000);

    //
    // Read response
    //
    NdisRawReadPortUchar(Adapter->IoAddr + NIC_COMMAND, &Tmp);

    if ((Tmp == (CR_NO_DMA | CR_STOP)) ||
        (Tmp == (CR_NO_DMA | CR_STOP | CR_START))
    )
    {
        return(TRUE);
    }
    else
    {
        return(FALSE);
    }
}
#ifdef RTL8139

#pragma NDIS_PAGEABLE_FUNCTION(CardSlotTest)


BOOLEAN CardSlotTest(
    IN PRTL8139_ADAPTER Adapter
)

/*++

Routine Description:

    Checks if the card is in an 8 or 16 bit slot and sets a flag in the
    adapter structure.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if all goes well, else FALSE.

--*/

{
    UCHAR Tmp;
    UCHAR RomCopy[32];
    UCHAR i;
	BOOLEAN found;

    //
    // Reset the chip
    //
    NdisRawReadPortUchar(Adapter->IoAddr + NIC_RESET, &Tmp);
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RESET, 0xFF);

    //
    // Go to page 0 and stop
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_STOP | CR_NO_DMA);

    //
    // Pause
    //
    NdisStallExecution(2000);

    //
    // Check that it is stopped
    //
    NdisRawReadPortUchar(Adapter->IoAddr + NIC_COMMAND, &Tmp);
    if (Tmp != (CR_NO_DMA | CR_STOP))
    {
        IF_LOUD(DbgPrint("Could not stop the card\n");)

        return(FALSE);
    }

    //
    // Setup to read from ROM
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_DATA_CONFIG,
        DCR_BYTE_WIDE | DCR_FIFO_8_BYTE | DCR_NORMAL
    );

    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_MASK, 0x0);

    //
    // Ack any interrupts that may be hanging around
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_STATUS, 0xFF);

    //
    // Setup to read in the ROM, the address and byte count.
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_LSB, 0x0);

    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_ADDR_MSB, 0x0);

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

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

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

    //
    // Read first 32 bytes in 16 bit mode
    //
	for (i = 0; i < 32; i++)
	{
		NdisRawReadPortUchar(Adapter->IoAddr + NIC_RACK_NIC, RomCopy + i);
	}

    IF_VERY_LOUD( DbgPrint("Resetting the chip\n"); )

    //
    // Reset the chip
    //
    NdisRawReadPortUchar(Adapter->IoAddr + NIC_RESET, &Tmp);
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RESET, 0xFF);

    //
    // Check ROM for 'B' (byte) or 'W' (word)
    // NOTE: If the buffer has bot BB and WW then use WW instead of BB
    IF_VERY_LOUD( DbgPrint("Checking slot type\n"); )

	found = FALSE;
	for (i = 16; i < 31; i++)
	{
		if (((RomCopy[i] == 'B') && (RomCopy[i+1] == 'B')) ||
			((RomCopy[i] == 'W') && (RomCopy[i+1] == 'W'))
		)
		{
			if (RomCopy[i] == 'B')
			{
				Adapter->EightBitSlot = TRUE;
				found = TRUE;
			}
			else
			{
				Adapter->EightBitSlot = FALSE;
				found = TRUE;
				break;		// Go no farther
			}
		}
	}

	if (found)
	{
		IF_VERY_LOUD( (Adapter->EightBitSlot?DbgPrint("8 bit slot\n"):
							  DbgPrint("16 bit slot\n")); )
	}
	else
	{
		//
		// If neither found -- then not an RTL8139
		//
		IF_VERY_LOUD( DbgPrint("Failed slot type\n"); )
	}

    return(found);
}

#endif // RTL8139




#pragma NDIS_PAGEABLE_FUNCTION(CardRamTest)

BOOLEAN
CardRamTest(
    IN PRTL8139_ADAPTER Adapter
    )

/*++

Routine Description:

    Finds out how much RAM the adapter has.  It starts at 1K and checks thru
    60K.  It will set Adapter->RamSize to the appropriate value iff this
    function returns TRUE.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if all goes well, else FALSE.

--*/

{
    PUCHAR RamBase, RamPointer;
    PUCHAR RamEnd;

	UCHAR TestPattern[]={ 0xAA, 0x55, 0xFF, 0x00 };
	PULONG pTestPattern = (PULONG)TestPattern;
	UCHAR ReadPattern[4];
	PULONG pReadPattern = (PULONG)ReadPattern;

    for (RamBase = (PUCHAR)0x400; RamBase < (PUCHAR)0x10000; RamBase += 0x400) {

        //
        // Write Test pattern
        //

        if (!CardCopyDown(Adapter, RamBase, TestPattern, 4)) {

            continue;

        }

        //
        // Read pattern
        //

        if (!CardCopyUp(Adapter, ReadPattern, RamBase, 4)) {

            continue;

        }

        IF_VERY_LOUD( DbgPrint("Addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x\n",
                               RamBase,
                               ReadPattern[0],
                               ReadPattern[1],
                               ReadPattern[2],
                               ReadPattern[3]
                              );
                    )


        //
        // If they are the same, find the end
        //

        if (*pReadPattern == *pTestPattern) {

            for (RamEnd = RamBase; !(PtrToUlong(RamEnd) & 0xFFFF0000); RamEnd += 0x400) {

                //
                // Write test pattern
                //

                if (!CardCopyDown(Adapter, RamEnd, TestPattern, 4)) {

                    break;

                }

                //
                // Read pattern
                //

                if (!CardCopyUp(Adapter, ReadPattern, RamEnd, 4)) {

                    break;

                }

                if (*pReadPattern != *pTestPattern) {

                    break;

                }

            }

            break;

        }

    }

    IF_LOUD( DbgPrint("RamBase 0x%x, RamEnd 0x%x\n", RamBase, RamEnd); )

    //
    // If not found, error out
    //

    if ((RamBase >= (PUCHAR)0x10000) || (RamBase == RamEnd)) {

        return(FALSE);

    }

    //
    // Watch for boundary case when RamEnd is maximum value
    //

    if ((ULONG_PTR)RamEnd & 0xFFFF0000) {

        RamEnd -= 0x100;

    }

    //
    // Check all of ram
    //

    for (RamPointer = RamBase; RamPointer < RamEnd; RamPointer += 4) {

        //
        // Write test pattern
        //

        if (!CardCopyDown(Adapter, RamPointer, TestPattern, 4)) {

            return(FALSE);

        }

        //
        // Read pattern
        //

        if (!CardCopyUp(Adapter, ReadPattern, RamBase, 4)) {

            return(FALSE);

        }

        if (*pReadPattern != *pTestPattern) {

            return(FALSE);

        }

    }

    //
    // Store Results
    //

    Adapter->RamBase = RamBase;
    Adapter->RamSize = (ULONG)(RamEnd - RamBase);

    return(TRUE);

}

#pragma NDIS_PAGEABLE_FUNCTION(CardInitialize)

BOOLEAN
CardInitialize(
    IN PRTL8139_ADAPTER Adapter
    )

/*++

Routine Description:

    Initializes the card into a running state.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if all goes well, else FALSE.

--*/

{
    UCHAR Tmp;
    USHORT i;

    //
    // Stop the card.
    //
    SyncCardStop(Adapter);

    //
    // Initialize the Data Configuration register.
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_DATA_CONFIG,
        DCR_AUTO_INIT | DCR_FIFO_8_BYTE
    );

    //
    // Set Xmit start location
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_START, 0xA0);

    //
    // Set Xmit configuration
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_CONFIG, 0x0);

    //
    // Set Receive configuration
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RCV_CONFIG, RCR_MONITOR);

    //
    // Set Receive start
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_PAGE_START, 0x4);

    //
    // Set Receive end
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_PAGE_STOP, 0xFF);

    //
    // Set Receive boundary
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_BOUNDARY, 0x4);

    //
    // Set Xmit bytes
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_COUNT_LSB, 0x3C);
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_XMIT_COUNT_MSB, 0x0);

    //
    // Pause
    //
    NdisStallExecution(2000);

    //
    // Ack all interrupts that we might have produced
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_STATUS, 0xFF);

    //
    // Change to page 1
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_PAGE1 | CR_STOP);

    //
    // Set current
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_CURRENT, 0x4);

    //
    // Back to page 0
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_COMMAND, CR_PAGE0 | CR_STOP);

    //
    // Pause
    //
    NdisStallExecution(2000);

    //
    // Check that Command register reflects this last command
    //
    NdisRawReadPortUchar(Adapter->IoAddr + NIC_COMMAND, &Tmp);
    if (!(Tmp & CR_STOP))
    {
        IF_LOUD(DbgPrint("Invalid command register\n");)

        return(FALSE);
    }

    //
    // Do initialization errata
    //
    NdisRawWritePortUchar(Adapter->IoAddr + NIC_RMT_COUNT_LSB, 55);

    //
    // Setup for a read
    //
    NdisRawWritePortUchar(
        Adapter->IoAddr + NIC_COMMAND,
        CR_DMA_READ | CR_START
    );


    Adapter->EightBitSlot = TRUE;



    //
    // Mask Interrupts
    //

    NdisRawWritePortUchar(Adapter->IoAddr + NIC_INTR_MASK, 0x0);

    //
    // Setup the Adapter for reading ram
    //

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

    if (Adapter->EightBitSlot)
    {
        NdisRawWritePortUchar(
            Adapter->IoAddr + NIC_DATA_CONFIG,
            DCR_FIFO_8_BYTE | DCR_NORMAL | DCR_BYTE_WIDE
        );
    }
    else

⌨️ 快捷键说明

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