📄 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:
- 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
- Dchen 11-01-99 Modified for the new sample driver
*****************************************************************************/
//#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
//-----------------------------------------------------------------------------
#include "precomp.h"
#if defined(EVENT_TRACING)
#include "routines.tmh"
#endif
//-----------------------------------------------------------------------------
// Procedure: WaitScb
//
// Description: This routine checks to see if the D100 has accepted a command.
// It does so by checking the command field in the SCB, which will
// be zeroed by the D100 upon accepting a command. The loop waits
// for up to 600 milliseconds for command acceptance.
//
// Arguments:
// Adapter - ptr to Adapter object instance
//
// Returns:
// TRUE if the SCB cleared within 600 milliseconds.
// FALSE if it didn't clear within 600 milliseconds
//-----------------------------------------------------------------------------
__inline BOOLEAN
WaitScb(
IN PFDO_DATA FdoData
)
{
BOOLEAN bResult;
HW_CSR volatile *pCSRAddress = FdoData->CSRAddress;
MP_STALL_AND_WAIT(pCSRAddress->ScbCommandLow == 0, 600, bResult);
if(!bResult)
{
DebugPrint(ERROR, DBG_HW_ACCESS, "WaitScb failed, ScbCommandLow=%x\n", pCSRAddress->ScbCommandLow);
if(pCSRAddress->ScbCommandLow != 0x80)
{
//ASSERT(FALSE);
}
MP_SET_HARDWARE_ERROR(FdoData);
}
return bResult;
}
VOID
MdiWrite(
IN PFDO_DATA Adapter,
IN ULONG RegAddress,
IN ULONG PhyAddress,
IN USHORT DataValue
)
{
BOOLEAN bResult;
// 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
KeStallExecutionProcessor (20);
// wait 2 seconds for the mdi write to complete
MP_STALL_AND_WAIT(Adapter->CSRAddress->MDIControl & MDI_PHY_READY, 2000, bResult);
if (!bResult)
{
MP_SET_HARDWARE_ERROR(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.
// Recoverable - Whether the hardware error(if any)if recoverable or not
//
// Results:
// DataValue - The value that we read from the MII register.
//
// Returns:
// None
//-----------------------------------------------------------------------------
BOOLEAN
MdiRead(
IN PFDO_DATA Adapter,
IN ULONG RegAddress,
IN ULONG PhyAddress,
IN BOOLEAN Recoverable,
IN OUT PUSHORT DataValue
)
{
BOOLEAN bResult;
// Issue the read command to the MDI control register.
Adapter->CSRAddress->MDIControl = ((RegAddress << 16) |
(PhyAddress << 21) |
(MDI_READ << 26));
// wait 20usec before checking status
KeStallExecutionProcessor (20);
// Wait up to 2 seconds for the mdi read to complete
MP_STALL_AND_WAIT(Adapter->CSRAddress->MDIControl & MDI_PHY_READY, 2000, bResult);
if (!bResult)
{
if (!Recoverable)
{
MP_SET_NON_RECOVER_ERROR(Adapter);
}
MP_SET_HARDWARE_ERROR(Adapter);
return bResult;
}
*DataValue = (USHORT) Adapter->CSRAddress->MDIControl;
return bResult;
}
//-----------------------------------------------------------------------------
// 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 PFDO_DATA Adapter
)
{
BOOLEAN bResult;
KIRQL oldIrql;
// 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;
KeAcquireSpinLock(&Adapter->Lock, &oldIrql);
// 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;
KeReleaseSpinLock(&Adapter->Lock, oldIrql);
// wait up to 2 seconds for the dump/reset to complete
MP_STALL_AND_WAIT(Adapter->StatsCounters->CommandComplete == 0xA007, 2000, bResult);
if (!bResult)
{
MP_SET_HARDWARE_ERROR(Adapter);
return;
}
// Output the debug counters to the debug terminal.
DebugPrint(LOUD, DBG_IOCTLS, "Good Transmits %d\n", Adapter->StatsCounters->XmtGoodFrames);
DebugPrint(LOUD, DBG_IOCTLS, "Good Receives %d\n", Adapter->StatsCounters->RcvGoodFrames);
DebugPrint(LOUD, DBG_IOCTLS, "Max Collisions %d\n", Adapter->StatsCounters->XmtMaxCollisions);
DebugPrint(LOUD, DBG_IOCTLS, "Late Collisions %d\n", Adapter->StatsCounters->XmtLateCollisions);
DebugPrint(LOUD, DBG_IOCTLS, "Transmit Underruns %d\n", Adapter->StatsCounters->XmtUnderruns);
DebugPrint(LOUD, DBG_IOCTLS, "Transmit Lost CRS %d\n", Adapter->StatsCounters->XmtLostCRS);
DebugPrint(LOUD, DBG_IOCTLS, "Transmits Deferred %d\n", Adapter->StatsCounters->XmtDeferred);
DebugPrint(LOUD, DBG_IOCTLS, "One Collision xmits %d\n", Adapter->StatsCounters->XmtSingleCollision);
DebugPrint(LOUD, DBG_IOCTLS, "Mult Collision xmits %d\n", Adapter->StatsCounters->XmtMultCollisions);
DebugPrint(LOUD, DBG_IOCTLS, "Total Collisions %d\n", Adapter->StatsCounters->XmtTotalCollisions);
DebugPrint(LOUD, DBG_IOCTLS, "Receive CRC errors %d\n", Adapter->StatsCounters->RcvCrcErrors);
DebugPrint(LOUD, DBG_IOCTLS, "Receive Alignment errors %d\n", Adapter->StatsCounters->RcvAlignmentErrors);
DebugPrint(LOUD, DBG_IOCTLS, "Receive no resources %d\n", Adapter->StatsCounters->RcvResourceErrors);
DebugPrint(LOUD, DBG_IOCTLS, "Receive overrun errors %d\n", Adapter->StatsCounters->RcvOverrunErrors);
DebugPrint(LOUD, DBG_IOCTLS, "Receive CDT errors %d\n", Adapter->StatsCounters->RcvCdtErrors);
DebugPrint(LOUD, DBG_IOCTLS, "Receive short frames %d\n", Adapter->StatsCounters->RcvShortFrames);
// update packet counts
Adapter->GoodTransmits += Adapter->StatsCounters->XmtGoodFrames;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -