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

📄 eth_smsc911x.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <arch/eth.h>#include <target/io.h>#include <target/mem.h>#include <target/memzero.h>#include <target/net/eth.h>#include <target/net/eth_util.h>#include "eth_smsc911x.h"#include "board.h"#if defined(DEBUG_ETH)#define DEBUG_SMSC911X#endif#if defined(DEBUG_SMSC911X)#define DEBUG_EN_TRACE#define DEBUG_EN_WARNING#define DEBUG_EN_TESTCODE#endif#if defined(DEBUG_EN_TRACE)#define SMSC_TRACE(msg, args...) hprintf("SMSC: " msg "\n", ## args)#else#define SMSC_TRACE(msg, args...)#endif#if defined(DEBUG_EN_WARNING)#define SMSC_WARNING(msg, args...) SMSC_TRACE(msg, ## args)#else#define SMSC_WARNING(msg, args...)#endif#define SMSC_ASSERT(condition)#define TRUE	((BOOLEAN)1)#define FALSE	((BOOLEAN)0)#define HIBYTE(word)  ((BYTE)(((WORD)(word))>>8))#define LOBYTE(word)  ((BYTE)(((WORD)(word))&0x00FFU))#define HIWORD(dWord) ((WORD)(((DWORD)(dWord))>>16))#define LOWORD(dWord) ((WORD)(((DWORD)(dWord))&0x0000FFFFUL))#define ENODEV 1#define udelay(x) ({volatile int t=50;while(t){t--;};})#define mdelay(x) ({volatile int t=50000;while(t){t--;};})PRIVATE_DATA _privateData;PPRIVATE_DATA privateData = &_privateData;PLATFORM_DATA _platformData;PPLATFORM_DATA platformData = &_platformData;unsigned char *EthTxBuffer = (unsigned char *)0x80000000;unsigned char *EthRxBuffer = (unsigned char *)0x80100000;#define MIN_PACKET_SIZE 60#define OLD_REGISTERS(privData)                    \	(((privData->dwIdRev&0x0000FFFFUL)==0UL)&& \	 ((privData->dwFpgaRev)>=0x01)&&           \	 ((privData->dwFpgaRev)<=0x25))/************************************************************************* * *************************************************************************/inline void Platform_SetRegDW(DWORD dwLanBase,		  DWORD dwOffset,		  DWORD dwVal){#if REVA  *(volatile u16 *)((dwLanBase) + ((dwOffset) << 1)) = ((dwVal) & 0xffff);  *(volatile u16 *)((dwLanBase) + (((dwOffset) + 2) << 1)) = (((dwVal)>>16) & 0xffff);#else  (*(volatile DWORD *)(dwLanBase+dwOffset))=dwVal;#endif}/************************************************************************* * *************************************************************************/inline DWORD Platform_GetRegDW(DWORD dwLanBase,		  DWORD dwOffset){#if REVA  u32 val;  val =     (*(volatile u16 *)((dwLanBase) + ((dwOffset)<<1))) |    ((*(volatile u16 *)((dwLanBase) + (((dwOffset) + 2)<<1)))<<16);  return val;#else  return (*(volatile DWORD *)(dwLanBase+dwOffset));#endif}/************************************************************************* * *************************************************************************/#include <mx3/ioregs.h>#include <target/htypes.h>static voideth_armadillo5x0_init(void){  mxc_set_mux(MUX_PIN(GPIO1_0),	MUX_O_GPIO | MUX_I_GPIO);  mxc_set_mux(MUX_PIN(GPIO1_1),	MUX_O_GPIO | MUX_I_GPIO);  mxc_set_mux(MUX_PIN(CS3),	MUX_O_FUNC | MUX_I_FUNC);}DWORDPlatform_Initialize(PPLATFORM_DATA platformData,		    DWORD dwLanBase,DWORD dwBusWidth){	DWORD mode=0;	DWORD test=0;	platformData->dwBitWidth=0;	platformData->dwIdRev=0;	SMSC_TRACE("--> Platform_Initialize()");	eth_armadillo5x0_init();	if(dwLanBase==0x0UL) {		dwLanBase=LAN_CSBASE;		SMSC_TRACE("Using dwLanBase==%p",dwLanBase);	}	if(dwLanBase!=LAN_CSBASE) {		SMSC_WARNING("PlatformInitialize: resetting dwLanBase from %p to %p", dwLanBase, LAN_CSBASE);		dwLanBase=LAN_CSBASE;	}#if defined(CONFIG_SUZAKU)	/* need to access register before it'll sets endian. */	*(volatile unsigned long *) (dwLanBase+BYTE_TEST);	/* Endian Register */	*(volatile unsigned long *) (dwLanBase+ENDIAN) = 0xffffffff;#endif	switch(dwBusWidth) {	case 16:		mode=2;		platformData->dwBitWidth=16;		test = Platform_GetRegDW(dwLanBase, BYTE_TEST);		if(test==0x87654321) {			SMSC_TRACE(" 16 bit mode assigned and verified");		} else {			SMSC_WARNING(" failed to verify assigned 16 bit mode");			dwLanBase=0;		};break;	case 32:		mode=1;		platformData->dwBitWidth=32;		test = Platform_GetRegDW(dwLanBase, BYTE_TEST);		if(test==0x87654321) {			SMSC_TRACE(" 32 bit mode assigned and verified");		} else {			SMSC_WARNING(" failed to verify assigned 32 bit mode");			dwLanBase=0;		};break;	default:		mode=1;		platformData->dwBitWidth=32;		{			WORD dummy=0;			test = Platform_GetRegDW(dwLanBase, BYTE_TEST);			dummy = Platform_GetRegDW(dwLanBase, BYTE_TEST);			if(test==0x87654321UL) {				SMSC_TRACE(" 32 bit mode detected");			} else {				SMSC_TRACE(" 32 bit mode not detected, test=%p",test);				platformData->dwBitWidth=16;				test = Platform_GetRegDW(dwLanBase, BYTE_TEST);				if(test==0x87654321UL) {					SMSC_TRACE(" 16 bit mode detected");					mode=2;				} else {					SMSC_WARNING(" neither 16 nor 32 bit mode detected.");					dwLanBase=0;				}			}			dummy=dummy;/* make lint happy */		};break;	}	if(dwLanBase!=0) {	  DWORD idRev = Platform_GetRegDW(dwLanBase, ID_REV);		platformData->dwIdRev=idRev;		switch(idRev&0xFFFF0000) {		case 0x01180000UL:		case 0x01170000UL:		case 0x01120000UL:			switch(mode) {			case 1:/* 32 bit mode */				platformData->dwBitWidth=32;				break;			case 2:/* 16 bit mode */				platformData->dwBitWidth=16;				break;			default:				break;/* make lint happy */			};			break;		default:			break;/* make lint happy */		}	}	SMSC_TRACE("<-- Platform_Initialize()");	return dwLanBase;}/************************************************************************* * *************************************************************************/#if defined(CONFIG_SUZAKU)static inline unsigned long __dword_swap(unsigned long v){	unsigned long _v;	_v =  ((v & 0x000000ff) << 24);	_v |= ((v & 0x0000ff00) << 8);	_v |= ((v & 0x00ff0000) >> 8);	_v |= ((v & 0xff000000) >> 24);	return _v;}#endif/************************************************************************* * *************************************************************************/static void Platform_WriteFifo(DWORD dwLanBase,		   DWORD *pdwBuf,		   DWORD dwDwordCount){	volatile DWORD *pdwReg;#if !REVA	pdwReg = (volatile DWORD *)(dwLanBase+TX_DATA_FIFO);#endif	while(dwDwordCount)	{#if defined(CONFIG_SUZAKU)		*pdwReg = __dword_swap(*pdwBuf++);#else#if !REVA		*pdwReg = *pdwBuf++;#else		/*a500 rev.a*/		Platform_SetRegDW(dwLanBase, TX_DATA_FIFO, *pdwBuf++);#endif#endif		dwDwordCount--;	}}/************************************************************************* * *************************************************************************/static void Platform_ReadFifo(DWORD dwLanBase,		  DWORD *pdwBuf,		  DWORD dwDwordCount){#if !REVA	const volatile DWORD * const pdwReg = 		(const volatile DWORD * const)(dwLanBase+RX_DATA_FIFO);#else	/*a500 rev.a*/	const volatile DWORD * const pdwReg = 		(const volatile DWORD * const)(dwLanBase+(RX_DATA_FIFO<<1));#endif		while (dwDwordCount)	{#if defined(DEBUG_EN_TESTCODE)		if(!(Lan_GetRegDW(RX_FIFO_INF) & RX_FIFO_INF_RXDUSED_)){			SMSC_WARNING("RX_DATA_FIFO underrun\n");		}#endif#if defined(CONFIG_SUZAKU)		*pdwBuf++ = __dword_swap(*pdwReg);#else#if !REVA		*pdwBuf++ = *pdwReg;#else		*pdwBuf++ = Platform_GetRegDW(dwLanBase, RX_DATA_FIFO);#endif#endif		dwDwordCount--;	}}/************************************************************************* * *************************************************************************/static BOOLEANMacNotBusy(PPRIVATE_DATA privateData, int dummy){	int i=0;	/* wait for MAC not busy, w/ timeout */	for(i=0;i<40;i++)	{		if((Lan_GetRegDW(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY_)==(0UL)) {			return TRUE;		}	}	SMSC_WARNING("timeout waiting for MAC not BUSY. MAC_CSR_CMD = %p",		Lan_GetRegDW(MAC_CSR_CMD));	return FALSE;}/************************************************************************* * *************************************************************************/static DWORD Mac_GetRegDW(PPRIVATE_DATA privateData,DWORD dwRegOffset){	DWORD result=0xFFFFFFFFUL;	DWORD dwTemp=0;	/* wait until not busy */	if (Lan_GetRegDW(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY_)	{		SMSC_WARNING("Mac_GetRegDW() failed, MAC already busy at entry");		goto DONE;	}	/* send the MAC Cmd w/ offset */	Lan_SetRegDW(MAC_CSR_CMD,		((dwRegOffset & 0x000000FFUL) | 		MAC_CSR_CMD_CSR_BUSY_ | MAC_CSR_CMD_R_NOT_W_));	dwTemp=Lan_GetRegDW(BYTE_TEST);/* to flush previous write */	dwTemp=dwTemp;	/* wait for the read to happen, w/ timeout */	if (!MacNotBusy(privateData,0))	{		SMSC_WARNING("Mac_GetRegDW() failed, waiting for MAC not busy after read");		goto DONE;	} else {	  /* finally, return the read data */		result=Lan_GetRegDW(MAC_CSR_DATA);	}DONE:	return result;}/************************************************************************* * *************************************************************************/static void Mac_SetRegDW(PPRIVATE_DATA privateData,DWORD dwRegOffset,DWORD dwVal){	DWORD dwTemp=0;	if (Lan_GetRegDW(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY_)	{		SMSC_WARNING("Mac_SetRegDW() failed, MAC already busy at entry");		goto DONE;	}	/* send the data to write */	Lan_SetRegDW(MAC_CSR_DATA,dwVal);	/* do the actual write */	Lan_SetRegDW(MAC_CSR_CMD,((dwRegOffset & 0x000000FFUL) | MAC_CSR_CMD_CSR_BUSY_));	dwTemp=Lan_GetRegDW(BYTE_TEST);/* force flush of previous write */	dwTemp=dwTemp;	/* wait for the write to complete, w/ timeout */	if (!MacNotBusy(privateData,0))	{		SMSC_WARNING("Mac_SetRegDW() failed, waiting for MAC not busy after write");	}DONE:	return;}/************************************************************************* * *************************************************************************/static WORD Phy_GetRegW(PPRIVATE_DATA privateData,DWORD dwRegIndex){	DWORD dwAddr=0;	int i=0;	WORD result=0xFFFFU;	SMSC_ASSERT(privateData!=NULL);	SMSC_ASSERT(privateData->LanInitialized==TRUE);	SMSC_ASSERT(Vl_CheckLock(&(privateData->MacPhyLock),0));	/* confirm MII not busy */	if ((Mac_GetRegDW(privateData, MII_ACC) & MII_ACC_MII_BUSY_) != 0UL)	{		SMSC_WARNING("MII is busy in Phy_GetRegW???");		result=0;		goto DONE;	}	/* set the address, index & direction (read from PHY) */	dwAddr = ((privateData->dwPhyAddress&0x1FUL)<<11) | ((dwRegIndex & 0x1FUL)<<6);	Mac_SetRegDW(privateData, MII_ACC, dwAddr);	/* wait for read to complete w/ timeout */	for(i=0;i<100;i++) {		/* see if MII is finished yet */		if ((Mac_GetRegDW(privateData, MII_ACC) & MII_ACC_MII_BUSY_) == 0UL)		{			/* get the read data from the MAC & return i */			result=((WORD)Mac_GetRegDW(privateData, MII_DATA));			goto DONE;		}	}	SMSC_WARNING("timeout waiting for MII write to finish");DONE:	return result;}/************************************************************************* * *************************************************************************/static void Phy_SetRegW(PPRIVATE_DATA privateData,DWORD dwRegIndex,WORD wVal){	DWORD dwAddr=0;	int i=0;	SMSC_ASSERT(privateData!=NULL);	SMSC_ASSERT(privateData->LanInitialized==TRUE);	SMSC_ASSERT(Vl_CheckLock(&(privateData->MacPhyLock),0));	if(dwRegIndex==0) {		if((wVal&0x1200)==0x1200) {			privateData->wLastADVatRestart=privateData->wLastADV;		}	}	if(dwRegIndex==4) {		privateData->wLastADV=wVal;	}	/* confirm MII not busy */	if ((Mac_GetRegDW(privateData, MII_ACC) & MII_ACC_MII_BUSY_) != 0UL)	{		SMSC_WARNING("MII is busy in Phy_SetRegW???");		goto DONE;	}	/* put the data to write in the MAC */	Mac_SetRegDW(privateData, MII_DATA, (DWORD)wVal);	/* set the address, index & direction (write to PHY) */	dwAddr = ((privateData->dwPhyAddress&0x1FUL)<<11) | ((dwRegIndex & 0x1FUL)<<6) | MII_ACC_MII_WRITE_;	Mac_SetRegDW(privateData, MII_ACC, dwAddr);	/* wait for write to complete w/ timeout */	for(i=0;i<100;i++) {		/* see if MII is finished yet */		if ((Mac_GetRegDW(privateData, MII_ACC) & MII_ACC_MII_BUSY_) == 0UL)		{			goto DONE;		}	}	SMSC_WARNING("timeout waiting for MII write to finish");DONE:	return;}/************************************************************************* * *************************************************************************/static DWORD Phy_LBT_GetTxStatus(PPRIVATE_DATA privateData){	DWORD result=Lan_GetRegDW(TX_FIFO_INF);	if(OLD_REGISTERS(privateData)) {		result&=TX_FIFO_INF_TSFREE_;		if(result!=0x00800000UL) {			result=Lan_GetRegDW(TX_STATUS_FIFO);		} else {			result=0;		}	} else {		result&=TX_FIFO_INF_TSUSED_;		if(result!=0x00000000UL) {			result=Lan_GetRegDW(TX_STATUS_FIFO);		} else {			result=0;		}	}	return result;}/************************************************************************* * *************************************************************************/#if defined(DEBUG_EN_TESTCODE)static BOOLEAN Phy_TransmitTestPacket(PPRIVATE_DATA privateData){  BYTE LoopBackTxPacket[70];	BOOLEAN result=FALSE;	DWORD dwLoopCount=0;	DWORD dwTxCmdA=0;	DWORD dwTxCmdB=0;	DWORD dwStatus=0;	/* write Tx Packet to 118 */	dwTxCmdA=		((((DWORD)(LoopBackTxPacket))&0x03UL)<<16) | /* DWORD alignment adjustment */		TX_CMD_A_INT_FIRST_SEG_ | TX_CMD_A_INT_LAST_SEG_ |		((DWORD)(MIN_PACKET_SIZE));	dwTxCmdB=		(((DWORD)(MIN_PACKET_SIZE))<<16) |		((DWORD)(MIN_PACKET_SIZE));	Lan_SetRegDW(TX_DATA_FIFO,dwTxCmdA);	Lan_SetRegDW(TX_DATA_FIFO,dwTxCmdB);

⌨️ 快捷键说明

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