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

📄 smc.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Clear the statistics registers
        WriteWord( BANKSEL_REG, BANK0 );
        ReadWord( COUNTER_REG );
        // Re-enable TXENA
        WriteWord( TCR_REG, TCR_REG_INIT );

        WriteWord( BANKSEL_REG, BANK2 );

        if (TX_INT & wInt) {
        	WriteWord (INTERRUPT_REG, TX_INT);		// Ack TX_INT
        }
        EDBG_DEBUGLED(LED_SENDFRAME_EXIT, wCompletionCode);
        
    } else {

        WriteWord( BANKSEL_REG, BANK2 );
        WriteWord (INTERRUPT_REG, TX_INT);		// Ack TX_INT

        EDBG_ADAPTERMSG(ZONE_SEND,("-SendFrame, success\n"));
        EDBG_DEBUGLED(LED_SENDFRAME_EXIT,0);
    }
    
    WriteWord (BANKSEL_REG, BANK2);        
    WriteWord (INTERRUPT_REG, wIntMask);

    return wCompletionCode;

} // SendFrame()



// This routine is called by a higher level routine if an error was detected by SendFrame()
//  returning non-zero.  The completion code that is returned is decoded here and error
//  message(s) are printed, prefixed by the supplied string.
static void SendFrameError( char *pszPrefix, UINT16 wCompletionCode ) {

    // Output any transmit error messages.  These correspond to the 
    //  EPH Status Register described on page 37 of the SMC91C94 spec.
    if (wCompletionCode & 0x8000)
        EdbgOutputDebugString( "%s::SendFrame()::Transmission Underrun\n", pszPrefix );
    if (wCompletionCode & 0x4000)
        EdbgOutputDebugString( "%s::SendFrame()::Link Test Failed\n", pszPrefix );
    if (wCompletionCode & 0x2000)
        EdbgOutputDebugString( "%s::SendFrame()::Receive Overrun\n", pszPrefix );
    if (wCompletionCode & 0x1000)
        EdbgOutputDebugString( "%s::SendFrame()::Statistics Counter Roll Over\n", pszPrefix );
    if (wCompletionCode & 0x0800)
        EdbgOutputDebugString( "%s::SendFrame()::Excessive Deferral\n", pszPrefix );
    if (wCompletionCode & 0x0400)
        EdbgOutputDebugString( "%s::SendFrame()::Lost Carrier\n", pszPrefix );
    if (wCompletionCode & 0x0200)
        EdbgOutputDebugString( "%s::SendFrame()::Late Collision\n", pszPrefix );
    if (wCompletionCode & 0x0080)
        EdbgOutputDebugString( "%s::SendFrame()::Transmission Deferred\n", pszPrefix );
    if (wCompletionCode & 0x0040)
        EdbgOutputDebugString( "%s::SendFrame()::Last Frame Was Broadcast\n", pszPrefix );
    if (wCompletionCode & 0x0020)
        EdbgOutputDebugString( "%s::SendFrame()::Signal Quality Error\n", pszPrefix );
    if (wCompletionCode & 0x0010)
        EdbgOutputDebugString( "%s::SendFrame()::16 Collisions Reached\n", pszPrefix );
    if (wCompletionCode & 0x0008)
        EdbgOutputDebugString( "%s::SendFrame()::Last Frame Was Multicast\n", pszPrefix );
    if (wCompletionCode & 0x0004)
        EdbgOutputDebugString( "%s::SendFrame()::Multiple Collisions Detected\n", pszPrefix );
    if (wCompletionCode & 0x0002)
        EdbgOutputDebugString( "%s::SendFrame()::Single Collion Detected\n", pszPrefix );
    if (wCompletionCode & 0x0001)
        EdbgOutputDebugString( "%s::SendFrame()::Transmit Successful\n", pszPrefix );
    EdbgOutputDebugString( "%s::SendFrame()::EPH Reg %Hh\n", pszPrefix, wCompletionCode );
}

#ifdef SMC_DUMP_FRAMES
static void DumpEtherFrame( BYTE *pFrame, WORD cwFrameLength ) {

    int i,j;

    EdbgOutputDebugString( "Frame Buffer Address: 0x%X\r\n", pFrame );
    EdbgOutputDebugString( "To: %B:%B:%B:%B:%B:%B  From: %B:%B:%B:%B:%B:%B  Type: 0x%H  Length: %u\r\n",
        pFrame[0], pFrame[1], pFrame[2], pFrame[3], pFrame[4], pFrame[5],
        pFrame[6], pFrame[7], pFrame[8], pFrame[9], pFrame[10], pFrame[11],
        ntohs(*((UINT16 *)(pFrame + 12))), cwFrameLength );
    for( i = 0; i < cwFrameLength / 16; i++ ) {
        for( j = 0; j < 16; j++ )
            EdbgOutputDebugString( " %B", pFrame[i*16 + j] );
        EdbgOutputDebugString( "\r\n" );
    }
    for( j = 0; j < cwFrameLength % 16; j++ )
        EdbgOutputDebugString( " %B", pFrame[i*16 + j] );
    EdbgOutputDebugString( "\r\n" );
}
#endif

// The read and write EEPROM routines access the 64 word by 16-bit EEPROM that is attached to the
//  91C94.  There are locations within the EEPROM that the chip does not need and can be used to
//  store other important information.  The memory map of the EEPROM is given in the ethernet.doc
//  spec.  The procedure used here for accessing these words is discussed on pages 88 and 89 of
//  the SMC91C94 spec.
BOOL SMCReadEEPROM( UINT16 EEPROMAddress , UINT16 *pwVal) {

    DWORD dwCurTime;
    WriteWord( BANKSEL_REG, BANK2 );
    WriteWord( POINTER_REG, (EEPROMAddress & 0x003F) | 0x6000 );
    WriteWord( BANKSEL_REG, BANK1 );
    WriteWord( CONTROL_REG, ReadWord(CONTROL_REG) | 0x0006 );

    // Loop until EEPROM data is retrieved
    dwCurTime = OEMEthGetSecs();
    
    while( ReadWord( CONTROL_REG ) & 0x0003 ) {
        if ((OEMEthGetSecs() - dwCurTime) > 2) {
            EdbgOutputDebugString("!SMCReadEEPROM read timed out\n");
            return FALSE;
        }
    }
    *pwVal = ReadWord( GENERAL_REG );
    return TRUE;
}

BOOL SMCWriteEEPROM( UINT16 EEPROMAddress, UINT16 Data ) {
    DWORD dwCurTime;
    WriteWord( BANKSEL_REG, BANK2 );
    WriteWord( POINTER_REG, (EEPROMAddress & 0x003F) | 0x6000 );
    WriteWord( BANKSEL_REG, BANK1 );
    WriteWord( GENERAL_REG, Data );
    WriteWord( CONTROL_REG, ReadWord(CONTROL_REG) | 0x0005 );

    // Loop until EEPROM data is written
    dwCurTime = OEMEthGetSecs();
    while( ReadWord( CONTROL_REG ) & 0x0003 ) {
        if ((OEMEthGetSecs() - dwCurTime) > 2) {
            EdbgOutputDebugString("!SMCWriteEEPROM read timed out\n");
            return FALSE;
        }
    }
    return TRUE;
}

// Read the value on the IOS lines, used to indicate the status of the switches on both the Odo
// Ethernet board, and the SMC eval board.
UINT16 SMCReadSwitches(void) {
    WriteWord( BANKSEL_REG, BANK3 );
    return ReadWord(MGMT_REG) >> 8;
}



////////////////////////////////////////////////////////////////////////////////
//	SMCComputeCrc()
//	
//	Description:
//
//		Runs the AUTODIN II CRC algorithm on buffer Buffer of length Length.
//
//	Arguments:
//
//		Buffer - the input buffer
//		Length - the length of Buffer
//
//	Return value:
//
//		The 32-bit CRC value.
//
//	Note:
//
//		This function is adopted from netcard\ne2000 miniport driver.
//		
ULONG
SMCComputeCrc(
    IN PUCHAR Buffer,
    IN UINT Length)
{
    ULONG Crc, Carry;
    UINT i, j;
    UCHAR CurByte;

    Crc = 0xffffffff;

    for (i = 0; i < Length; i++) {

        CurByte = Buffer[i];

        for (j = 0; j < 8; j++) {

            Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);

            Crc <<= 1;

            CurByte >>= 1;

            if (Carry) {

                Crc = (Crc ^ 0x04c11db6) | Carry;

            }

        }

    }

    return Crc;

}	//	SMCComputeCrc()



////////////////////////////////////////////////////////////////////////////////
//	SMCMulticastList()
//	
//	Description:
//
//		This function is used to insert multicast addresses to the h/w.
//
//	Arguments:
//
//		pucMulticastAddresses	:: The list of multicast addressses.
//		dwNoOfAddresses			:: The number of addresses in the list.
//
//	Return value:
//
//		TRUE if successful, FALSE otherwise.
//

BOOL
SMCMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
	UCHAR	NicMulticastRegs[8];		// contents of card multicast registers
	UINT	i;
	DWORD	dwCRC;

	EdbgOutputDebugString(
		"SMC111:: SMCMulticastList() set [%d] multicast list addrs.\r\n",
		dwNoOfAddresses);

#if 1

	for (i = 0 ; i < dwNoOfAddresses ; i++)
	{
		EdbgOutputDebugString(
			"SMC111:: Multicast[%d]  = %x-%x-%x-%x-%x-%x\r\n",
			i,
			pucMulticastAddresses[6*i + 0],
			pucMulticastAddresses[6*i + 1],
			pucMulticastAddresses[6*i + 2],
			pucMulticastAddresses[6*i + 3],
			pucMulticastAddresses[6*i + 4],
			pucMulticastAddresses[6*i + 5]);
	}

#endif

    //
    //	First turn all bits off.
    //

    memset (NicMulticastRegs, 0x00, sizeof(NicMulticastRegs));

    //
    // Now turn on the bit for each address in the multicast list.
    //

	for (i = 0 ; i < dwNoOfAddresses ; i++)
	{
		dwCRC = SMCComputeCrc(
					&pucMulticastAddresses[6*i],
					6);


		//
		//	Here is what the spec says:
		//	The hash value is defined as the six MSB of the CRC of the
		//	destination addr.
		//	The three MSB determine the register to be used (MT0..MT7)
		//	The other three determine the bit within the register.
		//

		NicMulticastRegs[dwCRC >> 29] |= (1 << ((dwCRC >> 26) & 0x07));
	}
    
#if 1	

	EdbgOutputDebugString(
		"SMC111:: Writing MulticastRegs = %x-%x-%x-%x-%x-%x-%x-%x\r\n",		
		NicMulticastRegs[0],
		NicMulticastRegs[1],
		NicMulticastRegs[2],
		NicMulticastRegs[3],
		NicMulticastRegs[4],
		NicMulticastRegs[5],
		NicMulticastRegs[6],
		NicMulticastRegs[7]);
	
#endif    

	//
	//	Finally, burn that in the h/w..
	//

	WriteWord (BANKSEL_REG, BANK3);

	WriteWord (MULTITAB_REG0, *(PWORD)&NicMulticastRegs[0]);
	WriteWord (MULTITAB_REG1, *(PWORD)&NicMulticastRegs[2]);
	WriteWord (MULTITAB_REG2, *(PWORD)&NicMulticastRegs[4]);
	WriteWord (MULTITAB_REG3, *(PWORD)&NicMulticastRegs[6]);	

    EdbgOutputDebugString(
        "SMC111:: Read back: %x-%x-%x-%x\r\n",
        ReadWord(MULTITAB_REG0),
        ReadWord(MULTITAB_REG1),
        ReadWord(MULTITAB_REG2),
        ReadWord(MULTITAB_REG3));

	
	return TRUE;

}	//	SMCMulticastList()



////////////////////////////////////////////////////////////////////////////////
//	SMCCurrentPacketFilter()
//	
//	Description:
//
//		This function is called to set the h/w filter.
//		We support:
//			PROMISCUOUS, ALL MULTICAST, BROADCAST, DIRECTED.
//
//	Arguments:
//
//		dwFilter::	The filter mode 
//
//	Return value:
//
//		TRUE if successful, FALSE otherwise.
//
void
SMCCurrentPacketFilter(DWORD	dwFilter)
{	
	//
	//	EDBG always receive directed and broadcast as a minimum.
	//	So our default will be RCR_REG_INIT..
	//

	WORD	wRxControlReg = RCR_REG_INIT;
    
	if (dwFilter & PACKET_TYPE_ALL_MULTICAST)
		wRxControlReg |= 0x04;

	if (dwFilter & PACKET_TYPE_PROMISCUOUS)
		wRxControlReg |= 0x02;
    

	//
	//	I think Broadcast is always received for smc111, so we don't
	//	need to do anything to this flag..
	//    

	EdbgOutputDebugString("SMC111:: Set filter to : [0x%x]\r\n",
		wRxControlReg);
		
	WriteWord (BANKSEL_REG, BANK0);
	WriteWord (RCR_REG, wRxControlReg);

}	//	SMCCurrentPacketFilter()

⌨️ 快捷键说明

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