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

📄 e100bexcard.cpp

📁 nmE100bex网卡驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Parameters:       
//		None
// IRQL: 
//		
// Return Mode:
//
// Returns:
//      TRUE - The receive unit is started
//      FALSE - The receive unit is not started
// NOTE:
//      
BOOLEAN E100bexCard::ReceiveUnitStarted()
{
    // If the receiver is ready, return TRUE.
    if (( USHORT(m_CSRStruc.ScbStatus) & SCB_RUS_MASK ) == SCB_RUS_READY)
	{
        return TRUE;
	}

	return FALSE;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::StartReceiveUnit
//
//	This routine checks the status of the 82557's receive unit(RU),
//              and starts the RU if it was not already active.  However,
//              before restarting the RU, the driver cleans up any recent
//              pending receives (this is very important).
//
// Parameters:       
//		None
// IRQL: 
//		
// Return Mode:
//
// Returns:
//      TRUE - If we indicated any receives during this function call
//      FALSE - If we didn't indicate any receives
// NOTE:
//      
VOID E100bexCard::StartReceiveUnit(PNDIS_PHYSICAL_ADDRESS pPhysAddr)
{
	ASSERT( pPhysAddr );

    // Wait for the SCB to clear before we set the general pointer
    if ( FALSE == WaitScb() )
	{
        ASSERT(0);
	}

    // Set the SCB General Pointer to point the current Rfd
    m_CSRStruc.ScbGeneralPointer = NdisGetPhysicalAddressLow(*pPhysAddr);

    // Issue the SCB RU start command
    IssueScbCommand(SCB_RUC_START, FALSE);

    // wait for the command to be accepted
    WaitScb();

    UINT WaitCount = 80000;

    // wait for RUS to be Ready
    while (WaitCount != 0)
    {
        if (( USHORT(m_CSRStruc.ScbStatus) & SCB_RUS_MASK) == SCB_RUS_READY)
            break;

        NdisStallExecution(10);
        WaitCount--;
    }
    if (!WaitCount)
    {
        TRACE("HARDWARE_NOT_RESPONDING");
    }

#if DBG
    // If we fall through, we have a problem.
    if (WaitCount == 0)
        TRACE("Failed, RU won't ready -- ScbStatus %08x\n", USHORT(m_CSRStruc.ScbStatus) );
#endif
}

////////////////////////////////////////////////////////////////////
// E100bexCard::IsInterrupting
//
//	This routine checks if the card is interrupting (the interrupt line
//	is high, and the interrupt is not masked.)  If the interrupt line
//	is already masked, then the driver is currently processing interrupts
//
// Parameters:       
//		None
// IRQL: 
//		DIRQL - called from Adapter class ISR
// Return Mode:
//
// Returns:
//      TRUE - If the card is interrupting
//      FALSE - Its not this card's interrupt or its masked
// NOTE:
//      

BOOLEAN	E100bexCard::IsInterrupting(void)
{
	if ((!( UCHAR(m_CSRStruc.ScbCommandHigh) & SCB_INT_MASK)) &&
        ( USHORT(m_CSRStruc.ScbStatus) & SCB_ACK_MASK))
    {
		return TRUE;
	}
	else
	{
		return FALSE;
	}
	
}

////////////////////////////////////////////////////////////////////
// E100bexCard::AckPendingInterrupts
//
//	This routine reads the ScbStatus register and checks the reason
//	for the interrupt.  If there are no interrupts to process,
//	returns FALSE.  If there are pending interrupts, ack the
//	interrupt and return TRUE.
//
// Parameters:       
//		None
// IRQL: 
//		Any - called from Adapter class DPC
// Return Mode:
//
// NOTE:
//      
BOOLEAN E100bexCard::AckPendingInterrupts(void)
{
    // Check the interrupt status bits of the SCB to determine the reason 
    // for the interrupt.

	volatile USHORT AckCommand = USHORT(m_CSRStruc.ScbStatus);

	TRACE3(("ScbStatus %04x\n", AckCommand))

	TRACE2(("E100bexCard::AckPendingInterrupts, ScbStatus = %04x\n", AckCommand))

	// Strip off the ACK bits.
	AckCommand &= SCB_ACK_MASK;

	// If there are no interrupts to process, then exit loop
	if (!AckCommand)
	{
		return FALSE;
	}

	m_CSRStruc.ScbStatus = AckCommand;

	return TRUE;
}


////////////////////////////////////////////////////////////////////
// E100bexCard::SetMcTimeoutFlag
//
// Set the McTimeoutFlag variable
//
// Parameters:
//		none
// IRQL: 
//		
// Return Mode:
//		
// NOTE:
//  This McTimeoutFlag will determine whether the
//	driver issues a periodic multicast command or not.  Issuing a periodic
//	multicast command will reset the 82557's internal receive state machine,
//	and bring the 82557 out of a "Receive-lockup" state. This is a documented
//	errata in the 82557 software developement manual.
//	If the end user didn't over-ride the McTimeout flag, then it should be
//	enabled only for 10mb operation, and only if the EEPROM indicates that
//	this adapter has a potential rcv-lockup problem.
//
VOID E100bexCard::SetMcTimeoutFlag()
{
    if (m_Ai.McTimeoutFlag == 2)
    {
        // Read the EEPROM flags register
        USHORT EepromFlags = ReadEEprom(EEPROM_FLAGS_WORD_3);
        if ((( m_Phy.GetCurrentLineSpeed() == 10) && (!(EepromFlags & EEPROM_FLAG_10MC))) ||
            (( m_Phy.GetCurrentLineSpeed() == 100) && (!(EepromFlags & EEPROM_FLAG_100MC))))
		{
            m_Ai.McTimeoutFlag = 1;
		}
        else
		{
            m_Ai.McTimeoutFlag = 0;
		}
    }

    TRACE("MC Timeout Flag = %x\n", m_Ai.McTimeoutFlag);
}

////////////////////////////////////////////////////////////////////
// E100bexCard::GetSharedMemorySize
//
// Get how much shared memory the E100bexCard needs.
//
// Parameters:
//		none
// IRQL: 
//		Any
// Return Mode:
//		Synchronous
// NOTE:
//		The Adapter will call this method prior to allocating
//	shared memory.
//
ULONG E100bexCard::GetSharedMemorySize(void)
{
	// return the size of the data structures that reside in shared memory
	// plus an additional 16 bytes (CARD_SHARED_MEM_ALIGNMENT) to paragraph align each structure
	return
		sizeof(SELF_TEST_STRUC) + CARD_SHARED_MEM_ALIGNMENT +
		sizeof(DUMP_AREA_STRUC) + CARD_SHARED_MEM_ALIGNMENT +
		sizeof(NON_TRANSMIT_CB) + CARD_SHARED_MEM_ALIGNMENT +
		sizeof(ERR_COUNT_STRUC) + CARD_SHARED_MEM_ALIGNMENT ;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::Setupsharedmemory
//
// Initalize E100bexCard data members with shared memory.
//
// Parameters:
//		CbPhys	- Physical address
//		ShMem	- KNdisSharedMemory object
// IRQL: 
//		Any
// Return Mode:
//		Synchronous
// NOTE:
//		The Adapter will call this method after allocating
//	shared memory.  The method will initialize the data members that
//	point into shared memory.  Alignment will be performed.  The
//	method returns the physical address pointing just beyond the 
//	area of shared memory used by E100bexCard.
//
ULONG E100bexCard::SetupSharedMemory(ULONG CbPhys, KNdisSharedMemory& ShMem)
{
	if ( !ShMem.IsValid() )
	{
		ASSERT(ShMem.IsValid());
		return CbPhys;
	}

	// Setup SelfTest Command Block Pointers
	PUCHAR pMem = m_Adapter.AlignSharedMemory(&CbPhys, CARD_SHARED_MEM_ALIGNMENT, ShMem);
	m_SelfTest = reinterpret_cast<PSELF_TEST_STRUC>(pMem);
	m_SelfTestPhys = CbPhys;
	CbPhys += sizeof(SELF_TEST_STRUC);

	// Setup non-Transmit Command Block Pointers
	pMem = m_Adapter.AlignSharedMemory(&CbPhys, CARD_SHARED_MEM_ALIGNMENT, ShMem);
	m_NonTxCmdBlock = reinterpret_cast<PNON_TRANSMIT_CB>(pMem);
    m_NonTxCmdBlockHdr = reinterpret_cast<PCB_HEADER_STRUC>(pMem);
	m_NonTxCmdBlockPhys = CbPhys;
	CbPhys += sizeof(NON_TRANSMIT_CB);

	// Setup dump buffer area
	pMem = m_Adapter.AlignSharedMemory(&CbPhys, CARD_SHARED_MEM_ALIGNMENT, ShMem);
	m_DumpSpace = reinterpret_cast<PDUMP_AREA_STRUC>(pMem);
	m_DumpSpacePhys = CbPhys;
	CbPhys += sizeof(DUMP_AREA_STRUC);

	// Setup stats counters area
	pMem = m_Adapter.AlignSharedMemory(&CbPhys, CARD_SHARED_MEM_ALIGNMENT, ShMem);
	m_StatsCounters = reinterpret_cast<PERR_COUNT_STRUC>(pMem);
	m_StatsCounterPhys = CbPhys;
	CbPhys += sizeof(ERR_COUNT_STRUC);

	TRACE("SelfTest area ptr=%x\n", m_SelfTest);
	TRACE("NonTxCmd Block ptr=%x\n", m_NonTxCmdBlock);
	TRACE("Dump buffer ptr=%x\n", m_DumpSpace);
	TRACE("Stats counts dump area ptr=%x\n", m_StatsCounters);

	return CbPhys;
}

////////////////////////////////////////////////////////////////////
// E100bexCard::SetPacketFilter
//
//
// Parameters:
//		NewPacketFilter
// IRQL: 
//		
// Return Mode:
//		
// NOTE:
//
NDIS_STATUS	E100bexCard::SetPacketFilter(ULONG NewPacketFilter, BOOLEAN bCheckExisting)
{
    TRACE("E100bexCard::SetPacketFilter\n");

    // Verify bits, if any bits are set that we don't support, leave
    if (NewPacketFilter &
        ~(NDIS_PACKET_TYPE_DIRECTED |
         NDIS_PACKET_TYPE_MULTICAST |
         NDIS_PACKET_TYPE_BROADCAST |
         NDIS_PACKET_TYPE_PROMISCUOUS |
         NDIS_PACKET_TYPE_ALL_MULTICAST))
    {
        TRACE("Filter Type %08x not supported\n", NewPacketFilter);
        return NDIS_STATUS_NOT_SUPPORTED;
    }

	if ( bCheckExisting )
	{
		// the filtering changes need to result in the hardware being reset.
		if (!((NewPacketFilter ^ m_PacketFilter) &
			(NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST |
			NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_PROMISCUOUS |
			NDIS_PACKET_TYPE_ALL_MULTICAST)))
		{
			TRACE("Filter Type %08x didn't change significantly, so return\n", NewPacketFilter);

			// save the new packet filter in our adapter object
			m_PacketFilter = NewPacketFilter;

			return NDIS_STATUS_SUCCESS;
		}
	}

    // save the new packet filter in our card object
    m_PacketFilter = NewPacketFilter;

    // Need to enable or disable broadcast and promiscuous support depending
    // on the new filter
    UCHAR NewParameterField = CB_557_CFIG_DEFAULT_PARM15;

    if (NewPacketFilter & NDIS_PACKET_TYPE_BROADCAST)
	{
        NewParameterField &= ~CB_CFIG_BROADCAST_DIS;
	}
    else
	{
        NewParameterField |= CB_CFIG_BROADCAST_DIS;
	}

    if (NewPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
	{
        NewParameterField |= CB_CFIG_PROMISCUOUS;
	}
    else
	{
        NewParameterField &= ~CB_CFIG_PROMISCUOUS;
	}

    NDIS_STATUS Status;

    // Only need to do something to the HW if the filter bits have changed.
    if ((m_OldParameterField != NewParameterField ) ||
        (NewPacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST))
    {
        TRACE("Filter Type %08x changed -- doing re-config\n", NewPacketFilter);

        m_OldParameterField = NewParameterField;
        m_NonTxCmdBlockHdr->CbCommand = CB_CONFIGURE;
        m_NonTxCmdBlockHdr->CbStatus = 0;
        m_NonTxCmdBlockHdr->CbLinkPointer = DRIVER_NULL;

        // First fill in the static (end user can't change) config bytes
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[0] = CB_557_CFIG_DEFAULT_PARM0;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[2] = CB_557_CFIG_DEFAULT_PARM2;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] = CB_557_CFIG_DEFAULT_PARM3;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[9] = CB_557_CFIG_DEFAULT_PARM9;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[10] = CB_557_CFIG_DEFAULT_PARM10;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[11] = CB_557_CFIG_DEFAULT_PARM11;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[12] = CB_557_CFIG_DEFAULT_PARM12;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[13] = CB_557_CFIG_DEFAULT_PARM13;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[14] = CB_557_CFIG_DEFAULT_PARM14;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] = CB_557_CFIG_DEFAULT_PARM15;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[16] = CB_557_CFIG_DEFAULT_PARM16;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[17] = CB_557_CFIG_DEFAULT_PARM17;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[18] = CB_557_CFIG_DEFAULT_PARM18;
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[20] = CB_557_CFIG_DEFAULT_PARM20;

        // next toggle in or out of promiscuous mode

        if (NewPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
        {
            // turn on save bad frames
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[6] =
                (CB_557_CFIG_DEFAULT_PARM6 | CB_CFIG_SAVE_BAD_FRAMES);

            // turn on save short frames
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
                (UCHAR) ((CB_557_CFIG_DEFAULT_PARM7 &
                (~(CB_CFIG_URUN_RETRY | CB_CFIG_DISC_SHORT_FRAMES))) |
                (m_Ai.AiUnderrunRetry << 1)
                );
        }

        else
        {
            // turn off save bad frames
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[6] =
                CB_557_CFIG_DEFAULT_PARM6;

            // turn off save short frames
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
                (UCHAR) ((CB_557_CFIG_DEFAULT_PARM7 &
                (~CB_CFIG_URUN_RETRY)) |
                (m_Ai.AiUnderrunRetry << 1)
                );
        }

        // Set the Tx and Rx Fifo limits
        m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[1] =
            (UCHAR) ((m_Ai.AiTxFifo << 4) | m_Ai.AiRxFifo);

        // set the MWI enable bit if needed
        if (m_Ai.MWIEnable)
		{
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] |= CB_CFIG_B3_MWI_ENABLE;
		}

        // Set the Tx and Rx DMA maximum byte count fields.
        if ((m_Ai.AiRxDmaCount) || (m_Ai.AiTxDmaCount))
        {
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] = (UCHAR) m_Ai.AiRxDmaCount;
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] = (UCHAR) (m_Ai.AiTxDmaCount | CB_CFIG_DMBC_EN);
        }
        else
        {
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
                CB_557_CFIG_DEFAULT_PARM4;
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] =
                CB_557_CFIG_DEFAULT_PARM5;
        }

        // Setup for MII or 503 operation.  The CRS+CDT bit should only be
        // set when operating in 503 mode.
        if (m_Phy.GetPhyAddress() == 32)
        {
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
                (CB_557_CFIG_DEFAULT_PARM8 & (~CB_CFIG_503_MII));
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
                (UCHAR) (NewParameterField | CB_CFIG_CRS_OR_CDT);
        }
        else
        {
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
                (CB_557_CFIG_DEFAULT_PARM8 | CB_CFIG_503_MII);
            m_NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -