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

📄 smc.c

📁 针对Intel Xscale PXA255的WinCE boot loader源代码包!极具参考价值!
💻 C
📖 第 1 页 / 共 3 页
字号:
    
    if (wInterruptReg & RX_OVRN_INT) {
        EDBG_DEBUGLED(LED_OVERRUN,wInterruptReg);
        EDBG_ADAPTERMSG(ZONE_WARNING,("RX_OVRN_INT\n"));
        WriteWord( INTERRUPT_REG, RX_OVRN_INT);
    }

    // This interrupt indicates that the RX buffer is not empty.  It just stays asserted until
    //  all the Frames are read out of the buffer.  I will accept one of these and set the fFrameReceived
    //  flag to indicate this to the GetFrame() routine, then I'll disable the interrupt from here.
    //  After GetFrame() gets called it will check the buffer and if it is empty it will re-enable the
    //  interrupt.
    if (wInterruptReg & RCV_INT) {
        fFrameReceived = 1;
        wInterruptReg &= (~RCV_INTM);
    }

    // Restore the interrupt mask register, with possible modification
    WriteWord( INTERRUPT_REG, (USHORT)(wInterruptReg & 0xFF00) );
    WriteWord( BANKSEL_REG, wBankSave );

    EDBG_ADAPTERMSG(ZONE_INTR,("-SMC_ISR: Ints pending: %X, fFrameReceived: %u\n", wInterruptReg, fFrameReceived));
}

#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;
	UINT16 controlRegister;
	BOOL readComplete;
    WriteWord( BANKSEL_REG, BANK2 );
    WriteWord( POINTER_REG, (USHORT)((EEPROMAddress & 0x003F) | 0x6000) );
    WriteWord( BANKSEL_REG, BANK1 );
	controlRegister = ReadWord((USHORT)(CONTROL_REG));
	WriteWord( BANKSEL_REG, BANK1 );
    WriteWord( CONTROL_REG, (USHORT)(controlRegister | 0x0006));

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

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

    // Loop until EEPROM data is written
    dwCurTime = OEMEthGetSecs();
	writeComplete = 1;
    while( writeComplete ) {
		//EdbgOutputDebugString("Waiting for STORE bit to clear.\n");
		WriteWord( BANKSEL_REG, BANK1 );
		writeComplete = ReadWord( CONTROL_REG ) & 0x0003;

        //if ((OEMEthGetSecs() - dwCurTime) > 5) {
        //	  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(
		"SMC91C94:: SMCMulticastList() set [%d] multicast list addrs.\r\n",
		dwNoOfAddresses);

	for (i = 0 ; i < dwNoOfAddresses ; i++)
	{
		EdbgOutputDebugString(
			"SMC9000:: 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]);
	}

    //
    //	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));
	}
    
	EdbgOutputDebugString(
		"SMC9000:: 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]);

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

	WriteWord (BANKSEL_REG, BANK3);

	WriteWord (MULTITAB_REG0, NicMulticastRegs[0]);
	WriteWord (MULTITAB_REG1, NicMulticastRegs[2]);
	WriteWord (MULTITAB_REG2, NicMulticastRegs[4]);
	WriteWord (MULTITAB_REG3, NicMulticastRegs[6]);	
	
	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 smc9000, so we don't
	//	need to do anything to this flag..
	//    

	EdbgOutputDebugString("SMC9000:: 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 + -