📄 e100bexcard.cpp
字号:
// 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 + -