⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e100bexcard.cpp

📁 nmE100bex网卡驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                (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 + -