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

📄 card.c

📁 使用网络驱动器接口标准开发的ne2000网卡的NT驱动.
💻 C
📖 第 1 页 / 共 5 页
字号:

#endif // NE2000

    //
    // Mask Interrupts
    //

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

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

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

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

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

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

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

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

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

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

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

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

        if (Tmp & ISR_RESET)
            break;

        NdisStallExecution(4);
    }

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

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

    //
    // Test for the amount of RAM
    //
    if (NE2000_ISA == Adapter->CardType)
    {
        if (CardRamTest(Adapter) == FALSE)
        {
            //
            // Stop the chip
            //
            SyncCardStop(Adapter);

            return(FALSE);
        }
    }
    else
    {
        //
        //  We know what it is for the pcmcia adapters,
        //  so don't waste time on detecting it.
        //
        Adapter->RamBase = (PUCHAR)0x4000;
        Adapter->RamSize = 0x4000;
    }

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

    return(TRUE);
}


#pragma NDIS_PAGEABLE_FUNCTION(CardReadEthernetAddress)

BOOLEAN CardReadEthernetAddress(
    IN PNE2000_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.
    //
    if (NE2000_PCMCIA == Adapter->CardType)
    {
#if 0
    
        NDIS_STATUS             Status;
        PUCHAR                  pAttributeWindow;
        NDIS_PHYSICAL_ADDRESS   AttributePhysicalAddress;
        //
        //  Setup the physical address for the attribute window.
        //
        NdisSetPhysicalAddressHigh(AttributePhysicalAddress, 0);
        NdisSetPhysicalAddressLow(
            AttributePhysicalAddress,
            Adapter->AttributeMemoryAddress
        );

        //
        //  We need to get the pcmcia information from the tuple.
        //
        Status = NdisMMapIoSpace(
                     (PVOID *)&pAttributeWindow,
                     Adapter->MiniportAdapterHandle,
                     AttributePhysicalAddress,
                     Adapter->AttributeMemorySize
                 );
        if (NDIS_STATUS_SUCCESS != Status)
        {
            //
            //  Failed to setup the attribute window.
            //
            return(FALSE);
        }

        //
        //  Read the ethernet address from the card.
        //
        for (c = 0; c < ETH_LENGTH_OF_ADDRESS; c++)
        {
			NdisReadRegisterUchar(
				(PUCHAR)(pAttributeWindow + CIS_NET_ADDR_OFFSET + c * 2),
				&Adapter->PermanentAddress[c]);
        }
#endif
		if (ETH_LENGTH_OF_ADDRESS != NdisReadPcmciaAttributeMemory(
													Adapter->MiniportAdapterHandle,
													CIS_NET_ADDR_OFFSET/2,
													Adapter->PermanentAddress,
													ETH_LENGTH_OF_ADDRESS
													))
		{
			return(FALSE);
		}

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

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

    IF_LOUD(
        DbgPrint(
            "Ne2000: 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 PNE2000_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->IoPAddr + NIC_COMMAND,
        CR_STOP | CR_NO_DMA | CR_PAGE0
    );

    NdisRawReadPortUchar(
        Adapter->IoPAddr + 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->IoPAddr + NIC_DATA_CONFIG,
            DCR_BYTE_WIDE | DCR_NORMAL | DCR_FIFO_8_BYTE
        );
    }
    else
    {
        NdisRawWritePortUchar(
            Adapter->IoPAddr + NIC_DATA_CONFIG,
            DCR_WORD_WIDE | DCR_NORMAL | DCR_FIFO_8_BYTE
        );
    }


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

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

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

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

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

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

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

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

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

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


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

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

    Filter = Adapter->PacketFilter;

    //
    // Write out the multicast addresses
    //
    for (i = 0; i < 8; i++)
    {
        NdisRawWritePortUchar(
            Adapter->IoPAddr + (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->IoPAddr + NIC_CURRENT,
        Adapter->Current
    );


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

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

    //
    // ... but it is still in loopback mode.
    //
    return(TRUE);
}

VOID CardStop(
    IN PNE2000_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->IoPAddr + NIC_RMT_COUNT_MSB, 0);
    NdisRawWritePortUchar(Adapter->IoPAddr + 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->IoPAddr+NIC_INTR_STATUS, &Tmp);
        if (Tmp & ISR_RESET)
            break;

        NdisStallExecution(500);
    }

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

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

    //
    // At this point the card is still in loopback mode.
    //
}

BOOLEAN CardReset(
    IN PNE2000_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,
            NE2000_ERRMSG_CARD_SETUP
        );

        return(FALSE);
    }

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

    return TRUE;
}



BOOLEAN CardCopyDownPacket(
    IN PNE2000_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.

⌨️ 快捷键说明

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