📄 e100bexcard.cpp
字号:
(UCHAR) (NewParameterField & (~CB_CFIG_CRS_OR_CDT));
}
// Setup Full duplex stuff
if (m_Ai.AiForceDpx == 1)
{
// If forced to half duplex
m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
(CB_557_CFIG_DEFAULT_PARM19 &
(~(CB_CFIG_FORCE_FDX| CB_CFIG_FDX_ENABLE)));
}
else
{
if (m_Ai.AiForceDpx == 2)
{
// If forced to full duplex
m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
(CB_557_CFIG_DEFAULT_PARM19 | CB_CFIG_FORCE_FDX);
}
else
{
// If auto-duplex
m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
CB_557_CFIG_DEFAULT_PARM19;
}
}
// if multicast all is being turned on, set the bit
if (NewPacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
{
m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] =
(CB_557_CFIG_DEFAULT_PARM21 | CB_CFIG_MULTICAST_ALL);
}
else
{
m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] =
CB_557_CFIG_DEFAULT_PARM21;
}
// Wait for the SCB to clear before we check the CU status.
WaitScb();
// If any transmits have been issued , then the CU will either be active,
// or in the suspended state. If the CU is active, then wait for
// it to be suspended.
if (m_Adapter.m_TransmitIdle == FALSE)
{
// Wait for suspended state
for (UINT i = 200000; i != 0; i--)
{
if (( USHORT(m_CSRStruc.ScbStatus) & SCB_CUS_MASK) != SCB_CUS_ACTIVE)
break;
NdisStallExecution(20);
}
if (!i)
{
TRACE("HARDWARE_NOT_RESPONDING\n");
Status = NDIS_STATUS_FAILURE;
}
// Restore the transmit software flags. After the multicast
// command is issued, the command unit will be idle, because the
// EL bit will be set in the multicast commmand block.
m_Adapter.m_TransmitIdle = TRUE;
m_Adapter.m_ResumeWait = TRUE;
}
// display the config info to the debugger
TRACE("Re-Issuing Configure command for filter change\n");
TRACE("Config Block at virt addr %x, phys address %x\n", &m_NonTxCmdBlockHdr->CbStatus, m_NonTxCmdBlockPhys);
for (UINT i=0; i < CB_CFIG_BYTE_COUNT; i++)
{
TRACE(" Config byte %x = %.2x\n", i, m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[i]);
}
m_CSRStruc.ScbGeneralPointer = m_NonTxCmdBlockPhys;
// Submit the configure command to the chip, and wait for it to complete.
if ( !SubmitCommandBlockAndWait() )
{
Status = NDIS_STATUS_NOT_ACCEPTED;
}
else
{
Status = NDIS_STATUS_SUCCESS;
}
return Status;
}
TRACE("Filter Type %08x did not change config\n", NewPacketFilter);
return NDIS_STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////
// E100bexCard::AbortReceiveUnit
//
//
// Parameters:
// None
// IRQL:
//
// Return Mode:
//
// NOTE:
//
VOID E100bexCard::AbortReceiveUnit()
{
IssueScbCommand(SCB_RUC_ABORT, TRUE);
}
////////////////////////////////////////////////////////////////////
// E100bexCard::UpdateStats
//
//
// Parameters:
// None
// IRQL:
//
// Return Mode:
//
// NOTE:
//
VOID E100bexCard::UpdateStats()
{
TRACE("E100bexCard::UpdateStats\n");
TRACE3(("\n"))
// The query is for a driver statistic, so we need to first
// update our statistics in software.
// clear the dump counters complete DWORD
m_StatsCounters->CommandComplete = 0;
// Dump and reset the hardware's statistic counters
IssueScbCommand(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.
m_Adapter.m_ResumeWait = TRUE;
// Now wait for the dump/reset to complete
for (UINT i=100000; i != 0; i--)
{
if (m_StatsCounters->CommandComplete == 0xA007)
break;
NdisStallExecution(20);
}
if (!i)
{
TRACE("HARDWARE_NOT_RESPONDING\n");
return;
}
// Output the debug counters to the debug terminal.
TRACE3(("Good Transmits %d\n", m_StatsCounters->XmtGoodFrames));
TRACE3(("Good Transmits %d\n", m_StatsCounters->XmtGoodFrames));
TRACE3(("Good Receives %d\n", m_StatsCounters->RcvGoodFrames));
TRACE3(("Max Collisions %d\n", m_StatsCounters->XmtMaxCollisions));
TRACE3(("Late Collisions %d\n", m_StatsCounters->XmtLateCollisions));
TRACE3(("Transmit Underruns %d\n", m_StatsCounters->XmtUnderruns));
TRACE3(("Transmit Lost CRS %d\n", m_StatsCounters->XmtLostCRS));
TRACE3(("Transmits Deferred %d\n", m_StatsCounters->XmtDeferred));
TRACE3(("One Collision xmits %d\n", m_StatsCounters->XmtSingleCollision));
TRACE3(("Mult Collision xmits %d\n", m_StatsCounters->XmtMultCollisions));
TRACE3(("Total Collisions %d\n", m_StatsCounters->XmtTotalCollisions));
TRACE3(("Receive CRC errors %d\n", m_StatsCounters->RcvCrcErrors));
TRACE3(("Receive Alignment errors %d\n", m_StatsCounters->RcvAlignmentErrors));
TRACE3(("Receive no resources %d\n", m_StatsCounters->RcvResourceErrors));
TRACE3(("Receive overrun errors %d\n", m_StatsCounters->RcvOverrunErrors));
TRACE3(("Receive CDT errors %d\n", m_StatsCounters->RcvCdtErrors));
TRACE3(("Receive short frames %d\n", m_StatsCounters->RcvShortFrames));
}
////////////////////////////////////////////////////////////////////
// E100bexCard::GetUpdatedStats
//
//
// Parameters:
// Stats
// IRQL:
//
// Return Mode:
//
// NOTE:
//
VOID E100bexCard::GetUpdatedStats(KNdisStats<ERR_COUNT_STRUC>& Stats)
{
// update packet counts
Stats->XmtGoodFrames += m_StatsCounters->XmtGoodFrames;
Stats->RcvGoodFrames += m_StatsCounters->RcvGoodFrames;
// update transmit error counts
Stats->XmtMaxCollisions += m_StatsCounters->XmtMaxCollisions;
Stats->XmtLateCollisions += m_StatsCounters->XmtLateCollisions;
Stats->XmtUnderruns += m_StatsCounters->XmtUnderruns;
Stats->XmtLostCRS += m_StatsCounters->XmtLostCRS;
Stats->XmtDeferred += m_StatsCounters->XmtDeferred;
Stats->XmtSingleCollision += m_StatsCounters->XmtSingleCollision;
Stats->XmtMultCollisions += m_StatsCounters->XmtMultCollisions;
Stats->XmtTotalCollisions += m_StatsCounters->XmtTotalCollisions;
// update receive error counts
Stats->RcvCrcErrors += m_StatsCounters->RcvCrcErrors;
Stats->RcvAlignmentErrors += m_StatsCounters->RcvAlignmentErrors;
Stats->RcvResourceErrors += m_StatsCounters->RcvResourceErrors;
Stats->RcvOverrunErrors += m_StatsCounters->RcvOverrunErrors;
Stats->RcvCdtErrors += m_StatsCounters->RcvCdtErrors;
Stats->RcvShortFrames += m_StatsCounters->RcvShortFrames;
}
////////////////////////////////////////////////////////////////////
// E100bexCard::ChangeMCAddresses
//
//
// Parameters:
// PrivateMulticastBuffer
// nAddressCount
// IRQL:
//
// Return Mode:
//
// NOTE:
//
NDIS_STATUS E100bexCard::ChangeMCAddresses(PUCHAR PrivateMulticastBuffer, UINT nAddressCount)
{
TRACE("E100bexCard::ChangeMCAddresses\n");
NDIS_STATUS Status = NDIS_STATUS_FAILURE;
if ( NULL == PrivateMulticastBuffer )
{
ASSERT( PrivateMulticastBuffer );
return Status;
}
TRACE1(("\n"))
TRACE1(("Configuring for %x mc addresses\n", nAddressCount))
// Holds the change that should be returned to the filtering package.
PUCHAR McAddress;
// Setup the command block for the multicast command.
for (UINT i = 0;(i < nAddressCount) && (i < MAX_MULTICAST_ADDRESSES);i++)
{
TRACE1((" mc %d =%.2x %.2x %.2x %.2x %.2x %.2x\n", i,
PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + 0],
PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + 1],
PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + 2],
PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + 3],
PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + 4],
PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + 5]
));
McAddress = &m_NonTxCmdBlock->NonTxCb.Multicast.McAddress[i*ETHERNET_ADDRESS_LENGTH];
for (UINT j = 0; j < ETH_LENGTH_OF_ADDRESS; j++)
{
*(McAddress++) = PrivateMulticastBuffer[i*ETH_LENGTH_OF_ADDRESS + j];
}
}
m_NonTxCmdBlock->NonTxCb.Multicast.McCount = (USHORT) (nAddressCount * ETH_LENGTH_OF_ADDRESS);
m_NonTxCmdBlockHdr->CbStatus = 0;
m_NonTxCmdBlockHdr->CbCommand = CB_MULTICAST;
// Wait for the SCB to clear before we check the CU status.
WaitScb();
// 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 (m_Adapter.m_TransmitIdle == FALSE)
{
// Wait for suspended state
for (UINT i = 200000; i != 0; i--)
{
if (( USHORT(m_CSRStruc.ScbStatus) & SCB_CUS_MASK) != SCB_CUS_ACTIVE)
break;
NdisStallExecution(20);
}
if (!i)
{
TRACE("HARDWARE_NOT_RESPONDING\n");
Status = NDIS_STATUS_FAILURE;
}
// Restore the transmit software flags. After the multicast command is
// issued, the command unit will be idle, because the EL bit will be
// set in the multicast commmand block.
m_Adapter.m_TransmitIdle = TRUE;
m_Adapter.m_ResumeWait = TRUE;
}
// Update the command list pointer.
m_CSRStruc.ScbGeneralPointer = m_NonTxCmdBlockPhys;
// Submit the multicast command to the adapter and wait for it to complete.
if ( !SubmitCommandBlockAndWait() )
{
Status = NDIS_STATUS_NOT_ACCEPTED;
}
else
{
Status = NDIS_STATUS_SUCCESS;
}
return Status;
}
////////////////////////////////////////////////////////////////////
// E100bexCard::StartTransmitUnit
//
//
// Parameters:
// TcbPhys
// IRQL:
//
// Return Mode:
//
// NOTE:
//
VOID E100bexCard::StartTransmitUnit(ULONG TcbPhys)
{
// Wait for the SCB to clear before we set the general pointer
WaitScb();
// Don't try to start the transmitter if the command unit is not
// idle ((not idle) == (Cu-Suspended or Cu-Active)).
if (( USHORT(m_CSRStruc.ScbStatus) & SCB_CUS_MASK) != SCB_CUS_IDLE)
{
TRACE("CU Not IDLE\n");
ASSERT(0);
NdisStallExecution(25);
}
m_CSRStruc.ScbGeneralPointer = TcbPhys;
IssueScbCommand(SCB_CUC_START, FALSE);
}
////////////////////////////////////////////////////////////////////
// E100bexCard::ResumeCommandUnit
//
//
// Parameters:
// None
// IRQL:
//
// Return Mode:
//
// NOTE:
//
VOID E100bexCard::ResumeCommandUnit()
{
// Issue a CU-Resume command to the device. We only need to do a
// WaitScb if the last command was NOT a RESUME.
if ( m_Adapter.m_ResumeWait )
{
if (!IssueScbCommand( SCB_CUC_RESUME, TRUE))
{
TRACE("CU-resume failed\n");
}
}
else
{
IssueScbCommand( SCB_CUC_RESUME, FALSE);
}
}
////////////////////////////////////////////////////////////////////
// E100bexCard::IssueSelectiveReset
//
//
// Parameters:
// None
// IRQL:
//
// Return Mode:
//
// NOTE:
//
VOID E100bexCard::IssueSelectiveReset()
{
TRACE2(("Entered E100bexCard::IssueSelectiveReset\n"))
// Wait for the SCB to clear before checking the CU status.
WaitScb();
// 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 (m_Adapter.m_TransmitIdle == FALSE)
{
// Wait for suspended state
for (UINT i=1000; (i != 0) && ( USHORT(m_CSRStruc.ScbStatus) & SCB_CUS_MASK) == SCB_CUS_ACTIVE; i--)
// while ((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) == SCB_CUS_ACTIVE)
{
TRACE("CU active -- wait for it to suspend. ScbStatus=%04x\n", m_CSRStruc.ScbStatus );
NdisStallExecution(20);
}
if (!i)
{
TRACE("HARDWARE_NOT_RESPONDING\n");
return;
}
// Check the current status of the receive unit
if (( USHORT(m_CSRStruc.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.
IssueScbCommand(SCB_RUC_ABORT, TRUE);
}
// Issue a selective reset.
TRACE("CU suspended. ScbStatus=%04x Issue selective reset\n", m_CSRStruc.ScbStatus);
m_CSRStruc.Port = PORT_SELECTIVE_RESET;
// stall 20 us (only need 10) after a port sel-reset command
NdisStallExecution(20);
for (i=100; i != 0; i--)
{
if ( ULONG(m_CSRStruc.Port) == 0)
break;
NdisStallExecution(10);
}
if (!i)
{
TRACE("HARDWARE_NOT_RESPONDING\n");
return;
}
// disable interrupts after issuing reset, because the int
// line gets raised when reset completes.
DisableInterrupt();
// Restore the transmit software flags.
m_Adapter.m_TransmitIdle = TRUE;
m_Adapter.m_ResumeWait = TRUE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -