📄 routines.c
字号:
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: NICIssueSelectiveReset
//
// Description: This routine will issue a selective reset, forcing the adapter
// the CU and RU back into their idle states. The receive unit
// will then be re-enabled if it was previously enabled, because
// an RNR interrupt will be generated when we abort the RU.
//
// Arguments:
// Adapter - ptr to Adapter object instance
//
// Returns:
// NOTHING
//-----------------------------------------------------------------------------
VOID
NICIssueSelectiveReset(
PFDO_DATA Adapter
)
{
NTSTATUS status;
BOOLEAN bResult;
// Wait for the SCB to clear before we check the CU status.
if (!MP_TEST_FLAG(Adapter, fMP_ADAPTER_HARDWARE_ERROR))
{
WaitScb(Adapter);
}
// If we have issued any transmits, then the CU will either be active, or
// in the suspended state. If the CU is active, then we wait for it to be
// suspended. If the the CU is suspended, then we need to put the CU back
// into the idle state by issuing a selective reset.
if (Adapter->TransmitIdle == FALSE)
{
// Wait up to 2 seconds for suspended state
MP_STALL_AND_WAIT((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_ACTIVE, 2000, bResult)
if (!bResult)
{
MP_SET_HARDWARE_ERROR(Adapter);
}
// Check the current status of the receive unit
if ((Adapter->CSRAddress->ScbStatus & SCB_RUS_MASK) != SCB_RUS_IDLE)
{
// Issue an RU abort. Since an interrupt will be issued, the
// RU will be started by the DPC.
status = D100IssueScbCommand(Adapter, SCB_RUC_ABORT, TRUE);
}
// Issue a selective reset.
DebugPrint(TRACE, DBG_HW_ACCESS, "CU suspended. ScbStatus=%04x Issue selective reset\n", Adapter->CSRAddress->ScbStatus);
Adapter->CSRAddress->Port = PORT_SELECTIVE_RESET;
// Wait after a port sel-reset command
KeStallExecutionProcessor (NIC_DELAY_POST_RESET);
// wait up to 2 ms for port command to complete
MP_STALL_AND_WAIT(Adapter->CSRAddress->Port == 0, 2, bResult)
if (!bResult)
{
MP_SET_HARDWARE_ERROR(Adapter);
}
// disable interrupts after issuing reset, because the int
// line gets raised when reset completes.
NICDisableInterrupt(Adapter);
// Restore the transmit software flags.
Adapter->TransmitIdle = TRUE;
Adapter->ResumeWait = TRUE;
}
}
VOID
NICIssueFullReset(
PFDO_DATA Adapter
)
{
BOOLEAN bResult;
NICIssueSelectiveReset(Adapter);
Adapter->CSRAddress->Port = PORT_SOFTWARE_RESET;
// wait up to 2 ms for port command to complete
MP_STALL_AND_WAIT(Adapter->CSRAddress->Port == 0, 2, bResult);
if (!bResult)
{
MP_SET_HARDWARE_ERROR(Adapter);
return;
}
NICDisableInterrupt(Adapter);
}
//-----------------------------------------------------------------------------
// Procedure: D100SubmitCommandBlockAndWait
//
// Description: This routine will submit a command block to be executed, and
// then it will wait for that command block to be executed. Since
// board ints will be disabled, we will ack the interrupt in
// this routine.
//
// Arguments:
// Adapter - ptr to Adapter object instance
//
// Returns:
// NDIS_STATUS_SUCCESS
// STATUS_DEVICE_DATA_ERROR
//-----------------------------------------------------------------------------
NTSTATUS
D100SubmitCommandBlockAndWait(
IN PFDO_DATA Adapter
)
{
NTSTATUS status;
BOOLEAN bResult;
// Points to the Non Tx Command Block.
volatile PNON_TRANSMIT_CB CommandBlock = Adapter->NonTxCmdBlock;
// Set the Command Block to be the last command block
CommandBlock->NonTxCb.Config.ConfigCBHeader.CbCommand |= CB_EL_BIT;
// Clear the status of the command block
CommandBlock->NonTxCb.Config.ConfigCBHeader.CbStatus = 0;
#if DBG
// Don't try to start the CU if the command unit is active.
if ((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) == SCB_CUS_ACTIVE)
{
DebugPrint(ERROR, DBG_HW_ACCESS, "Scb %p ScbStatus %04x\n", Adapter->CSRAddress, Adapter->CSRAddress->ScbStatus);
ASSERT(FALSE);
MP_SET_HARDWARE_ERROR(Adapter);
return(STATUS_DEVICE_DATA_ERROR);
}
#endif
// Start the command unit.
D100IssueScbCommand(Adapter, SCB_CUC_START, FALSE);
// Wait for the SCB to clear, indicating the completion of the command.
if (!WaitScb(Adapter))
{
return(STATUS_DEVICE_DATA_ERROR);
}
// Wait for some status, timeout value 3 secs
MP_STALL_AND_WAIT(CommandBlock->NonTxCb.Config.ConfigCBHeader.CbStatus & CB_STATUS_COMPLETE, 3000, bResult);
if (!bResult)
{
MP_SET_HARDWARE_ERROR(Adapter);
return(STATUS_DEVICE_DATA_ERROR);
}
// Ack any interrupts
if (Adapter->CSRAddress->ScbStatus & SCB_ACK_MASK)
{
// Ack all pending interrupts now
Adapter->CSRAddress->ScbStatus &= SCB_ACK_MASK;
}
// Check the status of the command, and if the command failed return FALSE,
// otherwise return TRUE.
if (!(CommandBlock->NonTxCb.Config.ConfigCBHeader.CbStatus & CB_STATUS_OK))
{
DebugPrint(ERROR, DBG_HW_ACCESS, "Command failed\n");
MP_SET_HARDWARE_ERROR(Adapter);
status = STATUS_DEVICE_DATA_ERROR;
}
else
status = STATUS_SUCCESS;
return(status);
}
//-----------------------------------------------------------------------------
// Procedure: GetConnectionStatus
//
// Description: This function returns the connection status that is
// a required indication for PC 97 specification from MS
// the value we are looking for is if there is link to the
// wire or not.
//
// Arguments: IN Adapter structure pointer
//
// Returns: NdisMediaStateConnected
// NdisMediaStateDisconnected
//-----------------------------------------------------------------------------
MEDIA_STATE
GetMediaState(
IN PFDO_DATA Adapter
)
{
USHORT MdiStatusReg = 0;
BOOLEAN bResult1;
BOOLEAN bResult2;
// Read the status register at phy 1
bResult1 = MdiRead(Adapter, MDI_STATUS_REG, Adapter->PhyAddress, TRUE, &MdiStatusReg);
bResult2 = MdiRead(Adapter, MDI_STATUS_REG, Adapter->PhyAddress, TRUE, &MdiStatusReg);
// if there is hardware failure, or let the state remains the same
if (!bResult1 || !bResult2)
{
return Adapter->MediaState;
}
if (MdiStatusReg & MDI_SR_LINK_STATUS)
return(Connected);
else
return(Disconnected);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -