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

📄 e100bexcard.cpp

📁 nmE100bex网卡驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// E100bexCard.cpp: implementation of the E100bexCard class.
//
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060  USA
//
// Copyright (c) 2000 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================
//
// Portions copied from Microsoft Windows 2000 DDK sample driver containing the
// following copyright
//
/****************************************************************************
** COPYRIGHT (C) 1994-1997 INTEL CORPORATION                               **
** DEVELOPED FOR MICROSOFT BY INTEL CORP., HILLSBORO, OREGON               **
** HTTP://WWW.INTEL.COM/                                                   **
** THIS FILE IS PART OF THE INTEL ETHEREXPRESS PRO/100B(TM) AND            **
** ETHEREXPRESS PRO/100+(TM) NDIS 5.0 MINIPORT SAMPLE DRIVER               **
****************************************************************************/


#include <kndis.h>
#include "E100bexInc.h"


////////////////////////////////////////////////////////////////////
// E100bexCard::E100bexCard
//
// Constructor for E100bex card object
//
// Parameters:
//		Adapter
//			Reference to the E100bexAdapter.  This is necessary so we can
//			use the adapter's handle in NDIS calls.
//		CSRRange
//			Reference to the initialized memory range where our CSR
//			registers reside on the card
// IRQL: 
//		PASSIVE_LEVEL
// Return Mode:
//		Synchronous
//
// NOTE:
//

E100bexCard::E100bexCard(E100bexAdapter& Adapter, KNdisMemoryRange& CSRRange, ADAPTER_INFO& Ai) :
	m_Adapter(Adapter),
	m_CSRStruc(CSRRange),
	m_Ai(Ai),
	m_DumpSpace(NULL),
	m_DumpSpacePhys(0),
	m_NonTxCmdBlock(NULL),
	m_NonTxCmdBlockHdr(NULL),
	m_NonTxCmdBlockPhys(0),
	m_StatsCounters(NULL),
	m_StatsCounterPhys(0),
	m_SelfTest(NULL),
	m_SelfTestPhys(0),
	m_Phy(Ai.PhyAddress,Ai.Connector, Ai.AiForceDpx, Ai.AiTempSpeed, Ai.Congest, m_CSRStruc.MDIControl )
{
}

////////////////////////////////////////////////////////////////////
// E100bexCard::ReadPermanentNodeAddress
//
// Reads the permanent node address stored in the EEprom on the card
//
// Parameters:
//		none
// IRQL: 
//		PASSIVE_LEVEL
// Return Mode:
//		Synchronous
//
// NOTE:
//
ETHERNET_ADDRESS E100bexCard::ReadPermanentNodeAddress(void)
{
	ETHERNET_ADDRESS PermanentNodeAddress;
	USHORT EepromWordValue;
	for (int i=0; i<6; i += 2)
	{
		EepromWordValue = ReadEEprom((USHORT) (EEPROM_NODE_ADDRESS_BYTE_0 + (i/2)));

		TRACE("EEPROM word %x reads %x\n",
			EEPROM_NODE_ADDRESS_BYTE_0 + (i/2), EepromWordValue);

		PermanentNodeAddress.m_bytes[i] = (UCHAR) EepromWordValue;
		PermanentNodeAddress.m_bytes[i+1] = (UCHAR) (EepromWordValue >> 8);
	}
	return PermanentNodeAddress;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::DisableInterrupt
//
// Disables the interrupt on the card.
//
// Parameters:
//		none
// IRQL: 
//		Any (called from the ISR)
// Return Mode:
//		Synchronous
//
// NOTE:
//
VOID E100bexCard::DisableInterrupt(void)
{
	TRACE2(("E100bexCard::DisableInterrupt() Entered\n"))

	// set the M (mask) bit in the adapter's CSR SCB command word
	m_CSRStruc.ScbCommandHigh = (UCHAR)SCB_INT_MASK;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::EnableInterrupt
//
// This routine enables interrupts at the hardware, by resetting
//              the M (mask) bit in the adapter's CSR SCB command word
//
// Parameters:
//		none
// IRQL: 
//		Any (called from the ISR)
// Return Mode:
//		Synchronous
//
// NOTE:
//
VOID E100bexCard::EnableInterrupt(void)
{
	TRACE2(("E100bexCard::EnableInterrupt() Entered\n"))

	// clear the M (mask) bit in the adapter's CSR SCB command word
	m_CSRStruc.ScbCommandHigh = (UCHAR)0;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::ReadEEprom
//
// This routine serially reads one word out of the EEPROM.
//
// Parameters:
//      Reg - EEPROM word to read.
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//		Returns contents of EEPROM word (Reg).
//
USHORT E100bexCard::ReadEEprom(IN USHORT Reg)
{
    USHORT x;
    USHORT data;

    // select EEPROM, reset bits, set EECS
    x = m_CSRStruc.EepromControl;

    x &= ~(EEDI | EEDO | EESK);
    x |= EECS;

    m_CSRStruc.EepromControl = x;

    // write the read opcode and register number in that order
    // The opcode is 3bits in length, reg is 6 bits long
    EEpromShiftOutBits(EEPROM_READ_OPCODE, 3);
    EEpromShiftOutBits(Reg, 6);

    // Now read the data (16 bits) in from the selected EEPROM word
    data = EEpromShiftInBits();

    EEpromCleanup();
    return data;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::EEpromRaiseClock
//
// This routine raises the EEPOM's clock input (EESK)
//
// Parameters:
//      x - Ptr to the EEPROM control register's current value
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//
VOID E100bexCard::EEpromRaiseClock(IN OUT USHORT *x)
{
    *x = *x | EESK;

    m_CSRStruc.EepromControl = *x;

    NdisStallExecution(100);
}

////////////////////////////////////////////////////////////////////
// E100bexCard::EEpromLowerClock
//
// This routine lowers the EEPOM's clock input (EESK)
//
// Parameters:
//      x - Ptr to the EEPROM control register's current value
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//
VOID E100bexCard::EEpromLowerClock(IN OUT USHORT *x)
{
    *x = *x & ~EESK;

    m_CSRStruc.EepromControl = *x;

    NdisStallExecution(100);
}

////////////////////////////////////////////////////////////////////
// E100bexCard::EEpromShiftOutBits
//
// This routine shifts data bits out to the EEPROM.
//
// Parameters:
//      data - data to send to the EEPROM.
//      count - number of data bits to shift out.
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//
VOID E100bexCard::EEpromShiftOutBits(USHORT data, USHORT count)
{
    USHORT x,mask;

    mask = 0x01 << (count - 1);
    x = m_CSRStruc.EepromControl;
    x &= ~(EEDO | EEDI);

    do
    {
        x &= ~EEDI;
        if (data & mask)
            x |= EEDI;

        m_CSRStruc.EepromControl = x;

        NdisStallExecution(100);
        EEpromRaiseClock(&x);
        EEpromLowerClock(&x);
        mask = mask >> 1;
    } while (mask);

    x &= ~EEDI;

    m_CSRStruc.EepromControl = x;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::EEpromShiftInBits
//
// This routine shifts data bits in from the EEPROM.
//
// Parameters:
//		none
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//		Returns the contents of that particular EEPROM word.
//      
USHORT E100bexCard::EEpromShiftInBits(void)

{
    USHORT x,d,i;

    x = m_CSRStruc.EepromControl;

    x &= ~( EEDO | EEDI);
    d = 0;

    for (i=0; i<16; i++)
    {
        d = d << 1;
        EEpromRaiseClock(&x);

        x = m_CSRStruc.EepromControl;

        x &= ~(EEDI);
        if (x & EEDO)
            d |= 1;

        EEpromLowerClock(&x);
    }

    return d;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::EEpromCleanup
//
// This routine returns the EEPROM to an idle state.
//
// Parameters:
//		none
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//      
VOID E100bexCard::EEpromCleanup(void)
{
    USHORT x;

    x = m_CSRStruc.EepromControl;

    x &= ~(EECS | EEDI);
    m_CSRStruc.EepromControl = x;

    EEpromRaiseClock(&x);
    EEpromLowerClock(&x);
}

////////////////////////////////////////////////////////////////////
// E100bexCard::SelfTest
//
//	This routine will issue PORT Self-test command to the D100.
//               
// Parameters:
//		none
// IRQL: 
//		
// Return Mode:
//		Synchronous
// Returns:
//    NDIS_STATUS_SUCCESS - If the adapter passes the self-test
//    NDIS_STATUS_FAILURE- If the adapter fails the self-test     
// NOTE:
//	The self-test will fail if the adapter's master-enable
//              bit is not set in the PCI Command Register, of if the adapter
//              is not seated in a PCI master-enabled slot.
//
NDIS_STATUS E100bexCard::SelfTest(void)
{
	TRACE("E100bexCard::SelfTest() Entered\n");

    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;

	// Issue a software reset to the adapter
	SoftwareReset();

	// Initialize the self-test command code
	ULONG dwSelfTestCommandCode = m_SelfTestPhys;
	dwSelfTestCommandCode |= PORT_SELFTEST;

    // Initialize the self-test signature and results DWORDS
    m_SelfTest->StSignature = 0;
    m_SelfTest->StResults = 0xffffffff;

	// Execute The PORT Self Test Command
    m_CSRStruc.Port = dwSelfTestCommandCode;

    // Wait 5 milliseconds for the self-test to complete
    StallExecution(5);

	// Check for unsuccessful self-test
    // if The First Self Test DWORD Still Zero, We've timed out.  If the second
    // DWORD is not zero then we have an error.
	if ( 0 == m_SelfTest->StSignature || 0 != m_SelfTest->StResults )
	{
		TRACE("Adapter self-test failed.\n");
		Status = NDIS_STATUS_FAILURE;
	}

	return Status;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::SoftwareReset
//
// This routine resets the D100 by issuing a PORT SOFTWARE RESET.
//
// Parameters:
//		none
// IRQL: 
//		
// Return Mode:
//		Synchronous
// NOTE:
//      
VOID E100bexCard::SoftwareReset(void)
{

    // Issue a PORT command with a data word of 0
    m_CSRStruc.Port = PORT_SOFTWARE_RESET;

    // wait 20 milliseconds for the reset to take effect
    StallExecution(20);

    // Mask off our interrupt line -- its unmasked after reset
    DisableInterrupt();
}

////////////////////////////////////////////////////////////////////
// E100bexCard::Init
//
// This routine will perform the initial configuration on the
//              the 82557 (D100) chip.  This will include loading the CU and
//              RU base values (0 in both cases), and calling other routines
//              that will issue a configure command to the 82257, notify the
//              82557 of its node address, and clear all of the on-chip
//              counters.
//
// Returns:
//      TRUE - If 82557 chip was initialized
//      FALSE - If 82557 failed initialization
//
BOOLEAN E100bexCard::Init(ETHERNET_ADDRESS NodeAddress)
{
    TRACE("E100bexCard::Init");

    // Issue a software reset to the D100
    SoftwareReset();

    // Load the CU BASE (set to 0, because we use linear mode)
    m_CSRStruc.ScbGeneralPointer = (ULONG)0;
	IssueScbCommand(SCB_CUC_LOAD_BASE,FALSE);

    // Wait for the SCB command word to clear before we set the general pointer
    WaitScb();

    // Load the RU BASE (set to 0, because we use linear mode)
    m_CSRStruc.ScbGeneralPointer = (ULONG)0;
    IssueScbCommand(SCB_RUC_LOAD_BASE, FALSE);

    // Configure the adapter
    if (!Configure())
	{
        return FALSE;
	}

⌨️ 快捷键说明

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