📄 routines.c
字号:
/****************************************************************************
** 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 **
****************************************************************************/
/****************************************************************************
Module Name:
routines.c
This driver runs on the following hardware:
- 82557/82558 based PCI 10/100Mb ethernet adapters
(aka Intel EtherExpress(TM) PRO Adapters)
Environment:
Kernel Mode - Or whatever is the equivalent on WinNT
Revision History
- JCB 8/14/97 Example Driver Created
*****************************************************************************/
#include "precomp.h"
#pragma hdrstop
#pragma warning (disable: 4514 4706)
//-----------------------------------------------------------------------------
// Procedure: MdiWrite
//
// Description: This routine will write a value to the specified MII register
// of an external MDI compliant device (e.g. PHY 100). The
// command will execute in polled mode.
//
// Arguments:
// Adapter - ptr to Adapter object instance
// RegAddress - The MII register that we are writing to
// PhyAddress - The MDI address of the Phy component.
// DataValue - The value that we are writing to the MII register.
//
// Returns:
// NOTHING
//-----------------------------------------------------------------------------
VOID
MdiWrite(
IN PD100_ADAPTER Adapter,
IN ULONG RegAddress,
IN ULONG PhyAddress,
IN USHORT DataValue
)
{
UINT counter;
DEBUGFUNC("MdiWrite");
TRACE3(Adapter, ("\n"));
// Issue the write command to the MDI control register.
Adapter->CSRAddress->MDIControl = (((ULONG) DataValue) |
(RegAddress << 16) |
(PhyAddress << 21) |
(MDI_WRITE << 26));
// wait 20usec before checking status
NdisStallExecution(20);
// poll for the mdi write to complete
for (counter = 100000; counter != 0; counter--)
{
if (Adapter->CSRAddress->MDIControl & MDI_PHY_READY)
break;
NdisStallExecution(20);
}
if (!counter)
{
HARDWARE_NOT_RESPONDING (Adapter);
}
}
//-----------------------------------------------------------------------------
// Procedure: MdiRead
//
// Description: This routine will read a value from the specified MII register
// of an external MDI compliant device (e.g. PHY 100), and return
// it to the calling routine. The command will execute in polled
// mode.
//
// Arguments:
// Adapter - ptr to Adapter object instance
// RegAddress - The MII register that we are reading from
// PhyAddress - The MDI address of the Phy component.
//
// Results:
// DataValue - The value that we read from the MII register.
//
// Returns:
// NOTHING
//-----------------------------------------------------------------------------
VOID
MdiRead(
IN PD100_ADAPTER Adapter,
IN ULONG RegAddress,
IN ULONG PhyAddress,
IN OUT PUSHORT DataValue
)
{
UINT counter;
DEBUGFUNC("MdiRead");
TRACE3(Adapter, ("\n"));
// Issue the read command to the MDI control register.
Adapter->CSRAddress->MDIControl = ((RegAddress << 16) |
(PhyAddress << 21) |
(MDI_READ << 26));
// wait 20usec before checking status
NdisStallExecution(20);
// poll for the mdi read to complete
for (counter = 100000; counter != 0; counter--)
{
if (Adapter->CSRAddress->MDIControl & MDI_PHY_READY)
break;
NdisStallExecution(20);
}
if (!counter)
{
HARDWARE_NOT_RESPONDING (Adapter);
return;
}
*DataValue = (USHORT) Adapter->CSRAddress->MDIControl;
}
//-----------------------------------------------------------------------------
// Procedure: DumpStatsCounters
//
// Description: This routine will dump and reset the 82557's internal
// Statistics counters. The current stats dump values will be
// added to the "Adapter's" overall statistics.
// Arguments:
// Adapter - ptr to Adapter object instance
//
// Returns:
// NOTHING
//-----------------------------------------------------------------------------
VOID
DumpStatsCounters(
IN PD100_ADAPTER Adapter
)
{
UINT i;
DEBUGFUNC("DumpStatsCounters");
TRACE3(Adapter, ("\n"));
DEBUGCHAR(Adapter,'D');
// The query is for a driver statistic, so we need to first
// update our statistics in software.
// clear the dump counters complete DWORD
Adapter->StatsCounters->CommandComplete = 0;
// Acquire a spinlock here because this is a static command
// Dump and reset the hardware's statistic counters
D100IssueScbCommand(Adapter, SCB_CUC_DUMP_RST_STAT, TRUE);
// Restore the resume transmit software flag. After the dump counters
// command is issued, we should do a WaitSCB before issuing the next send.
Adapter->ResumeWait = TRUE;
// Release SCB spinlock
// Now wait for the dump/reset to complete
for (i=100000; i != 0; i--)
{
if (Adapter->StatsCounters->CommandComplete == 0xA007)
break;
NdisStallExecution(20);
}
if (!i)
{
HARDWARE_NOT_RESPONDING (Adapter);
return;
}
// Output the debug counters to the debug terminal.
STATS(Adapter, ("Good Transmits %d\n", Adapter->StatsCounters->XmtGoodFrames));
STATS(Adapter, ("Good Receives %d\n", Adapter->StatsCounters->RcvGoodFrames));
STATS(Adapter, ("Max Collisions %d\n", Adapter->StatsCounters->XmtMaxCollisions));
STATS(Adapter, ("Late Collisions %d\n", Adapter->StatsCounters->XmtLateCollisions));
STATS(Adapter, ("Transmit Underruns %d\n", Adapter->StatsCounters->XmtUnderruns));
STATS(Adapter, ("Transmit Lost CRS %d\n", Adapter->StatsCounters->XmtLostCRS));
STATS(Adapter, ("Transmits Deferred %d\n", Adapter->StatsCounters->XmtDeferred));
STATS(Adapter, ("One Collision xmits %d\n", Adapter->StatsCounters->XmtSingleCollision));
STATS(Adapter, ("Mult Collision xmits %d\n", Adapter->StatsCounters->XmtMultCollisions));
STATS(Adapter, ("Total Collisions %d\n", Adapter->StatsCounters->XmtTotalCollisions));
STATS(Adapter, ("Receive CRC errors %d\n", Adapter->StatsCounters->RcvCrcErrors));
STATS(Adapter, ("Receive Alignment errors %d\n", Adapter->StatsCounters->RcvAlignmentErrors));
STATS(Adapter, ("Receive no resources %d\n", Adapter->StatsCounters->RcvResourceErrors));
STATS(Adapter, ("Receive overrun errors %d\n", Adapter->StatsCounters->RcvOverrunErrors));
STATS(Adapter, ("Receive CDT errors %d\n", Adapter->StatsCounters->RcvCdtErrors));
STATS(Adapter, ("Receive short frames %d\n", Adapter->StatsCounters->RcvShortFrames));
// update packet counts
Adapter->GoodTransmits += Adapter->StatsCounters->XmtGoodFrames;
Adapter->GoodReceives += Adapter->StatsCounters->RcvGoodFrames;
// update transmit error counts
Adapter->TxAbortExcessCollisions += Adapter->StatsCounters->XmtMaxCollisions;
Adapter->TxLateCollisions += Adapter->StatsCounters->XmtLateCollisions;
Adapter->TxDmaUnderrun += Adapter->StatsCounters->XmtUnderruns;
Adapter->TxLostCRS += Adapter->StatsCounters->XmtLostCRS;
Adapter->TxOKButDeferred += Adapter->StatsCounters->XmtDeferred;
Adapter->OneRetry += Adapter->StatsCounters->XmtSingleCollision;
Adapter->MoreThanOneRetry += Adapter->StatsCounters->XmtMultCollisions;
Adapter->TotalRetries += Adapter->StatsCounters->XmtTotalCollisions;
// update receive error counts
Adapter->RcvCrcErrors += Adapter->StatsCounters->RcvCrcErrors;
Adapter->RcvAlignmentErrors += Adapter->StatsCounters->RcvAlignmentErrors;
Adapter->RcvResourceErrors += Adapter->StatsCounters->RcvResourceErrors;
Adapter->RcvDmaOverrunErrors += Adapter->StatsCounters->RcvOverrunErrors;
Adapter->RcvCdtFrames += Adapter->StatsCounters->RcvCdtErrors;
Adapter->RcvRuntErrors += Adapter->StatsCounters->RcvShortFrames;
}
//-----------------------------------------------------------------------------
// Procedure: DoBogusMulticast
//
// Description: This routine will issue a multicast command to adapter. If the
// Adapter's receive unit is "locked-up", a multicast command will
// will reset and "un-lock" the receive unit. The multicast
// command that is issued here will be chained into the transmit
// list.
//
// Arguments:
// Adapter - ptr to Adapter object instance
//
// Returns:
// NOTHING
//-----------------------------------------------------------------------------
VOID
DoBogusMulticast(
IN PD100_ADAPTER Adapter
)
{
PD100SwTcb SwTcb;
PUCHAR McAddress;
UINT i, j;
#if DBG
USHORT x;
#endif
DEBUGFUNC("DoBogusMulticast");
TRACE3(Adapter, ("\n"));
DEBUGCHAR(Adapter,'B');
// Attempt to acquire a Software TCB for the packet
SwTcb = (PD100SwTcb) QueuePopHead(&Adapter->TxCBList);
if (SwTcb)
{
// Setup the pointer to the first MC Address
McAddress = (PUCHAR) &SwTcb->Tcb->TxCbTbdPointer;
McAddress += 2;
// the cast on an l-value is wierd, but needed because we are using
// a transmit structure to build a multicast add command
#pragma warning (disable: 4213)
// Setup the multicast address count
(USHORT) SwTcb->Tcb->TxCbTbdPointer =
(USHORT) (Adapter->NumberOfMcAddresses * ETH_LENGTH_OF_ADDRESS);
#pragma warning (default: 4213)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -