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

📄 lan91c111.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#define TS_SUCCESS	(0x0001)
#define TS_LOSTCAR	(0x0400)
#define TS_LATCOL	(0x0200)
#define TS_16COL	(0x0010)

/* Receive status bits */
#define RS_ALGNERR	(0x8000)
#define RS_BRODCAST	(0x4000)
#define RS_BADCRC	(0x2000)
#define RS_ODDFRAME	(0x1000)	// bug: the LAN91C111 never sets this on receive
#define RS_TOOLONG	(0x0800)
#define RS_TOOSHORT	(0x0400)
#define RS_MULTICAST	(0x0001)
#define RS_ERRORS	(RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) 

/************************************************************************
 * MII register numbering
*************************************************************************/
enum {
	MII_CONTROL = 0,
	MII_STATUS,
	MII_PHYID1,
	MII_PHYID2,
	MII_ADVERTISEMENT,
	MII_REMOTE_CAP,
	MII_CONFIG1 = 16,
	MII_CONFIG2,
	MII_STATUS_OUTPUT,
	MII_MASK,
	MII_RESERVED
};
/*
 * 0: control reg
 */
#define MII_CONTROL_RST		(1 << 15)
#define MII_CONTROL_LPBK	(1 << 14)
#define MII_CONTROL_SPEED	(1 << 13)
#define MII_CONTROL_ANEG_EN	(1 << 12)
#define MII_CONTROL_PDN		(1 << 11)
#define MII_CONTROL_MII_DIS	(1 << 10)
#define MII_CONTROL_ANEG_RST	(1 << 9)
#define MII_CONTROL_DPLX	(1 << 8)
#define MII_CONTROL_COLST	(1 << 7)
/*
 * 1: status reg
 */
#define MII_STATUS_CAP_T4	(1 << 15)
#define MII_STATUS_CAP_TXF	(1 << 14)
#define MII_STATUS_CAP_TXH	(1 << 13)
#define MII_STATUS_CAP_TF	(1 << 12)
#define MII_STATUS_CAP_TH	(1 << 11)
#define MII_STATUS_CAP_SUPR	(1 << 6)
#define MII_STATUS_ANEG_ACK	(1 << 5)
#define MII_STATUS_REM_FLT	(1 << 4)
#define MII_STATUS_CAP_ANEG	(1 << 3)
#define MII_STATUS_LINK		(1 << 2)
#define MII_STATUS_JAB		(1 << 1)
#define MII_STATUS_EXREG	(1 << 0)
/*
 * 2: phy id #1
 */
/*
 * 3: phy id #2
 */
#define MII_PART_MASK		(0x3f << 4)
#define MII_REV_MASK		(0x0f)
/*
 * 4: autonetotiation advertisement reg
 */
#define MII_ADVERTISEMENT_NP		(1 << 15)
#define MII_ADVERTISEMENT_ACK		(1 << 14)
#define MII_ADVERTISEMENT_RF		(1 << 13)
#define MII_ADVERTISEMENT_T4		(1 << 9)
#define MII_ADVERTISEMENT_TX_FDX	(1 << 8)
#define MII_ADVERTISEMENT_TX_HDX	(1 << 7)
#define MII_ADVERTISEMENT_10_FDX	(1 << 6)
#define MII_ADVERTISEMENT_10_HDX	(1 << 5)
#define MII_ADVERTISEMENT_CSMA		(1 << 0)
/*
 * 5: autonetotiation remote capability reg
 */
#define MII_REMOTE_CAP_NP		(1 << 15)
#define MII_REMOTE_CAP_ACK		(1 << 14)
#define MII_REMOTE_CAP_RF		(1 << 13)
#define MII_REMOTE_CAP_T4		(1 << 9)
#define MII_REMOTE_CAP_TX_FDX		(1 << 8)
#define MII_REMOTE_CAP_TX_HDX		(1 << 7)
#define MII_REMOTE_CAP_10_FDX		(1 << 6)
#define MII_REMOTE_CAP_10_HDX		(1 << 5)
#define MII_REMOTE_CAP_CSMA		(1 << 0)
/*
 * 16: configuration 1 reg
 */
#define MII_CONFIG1_LINKDIS		(1 << 15)
#define MII_CONFIG1_XMITDIS		(1 << 14)
#define MII_CONFIG1_XMITPDN		(1 << 13)
#define MII_CONFIG1_BYPSCR		(1 << 10)
#define MII_CONFIG1_UNSCDS		(1 << 9)
#define MII_CONFIG1_EQLZR		(1 << 8)
#define MII_CONFIG1_CABLE		(1 << 7)
#define MII_CONFIG1_RLVL0		(1 << 6)
#define MII_CONFIG1_TLVL3		(1 << 5)
#define MII_CONFIG1_TLVL2		(1 << 4)
#define MII_CONFIG1_TLVL1		(1 << 3)
#define MII_CONFIG1_TLVL0		(1 << 2)
#define MII_CONFIG1_TRF1		(1 << 1)
#define MII_CONFIG1_TRF0		(1 << 0)
/*
 * 17: configuration 2 reg
 */
#define MII_CONFIG2_APOLDIS		(1 << 5)
#define MII_CONFIG2_JABDIS		(1 << 4)
#define MII_CONFIG2_MREG		(1 << 3)
#define MII_CONFIG2_INTMDIO		(1 << 2)
/*
 * 18: status output reg
 */
#define MII_STATUS_OUTPUT_INT		(1 << 15)
#define MII_STATUS_OUTPUT_LNKFAIL	(1 << 14)
#define MII_STATUS_OUTPUT_LOSSSYNC	(1 << 13)
#define MII_STATUS_OUTPUT_CWRD		(1 << 12)
#define MII_STATUS_OUTPUT_SSD		(1 << 11)
#define MII_STATUS_OUTPUT_ESD		(1 << 10)
#define MII_STATUS_OUTPUT_RPOL		(1 << 9)
#define MII_STATUS_OUTPUT_JAB		(1 << 8)
#define MII_STATUS_OUTPUT_SPDDET	(1 << 7)
#define MII_STATUS_OUTPUT_DPLXDET	(1 << 6)
/*
 * 19: mask reg
 */
#define MII_MASK_MINT			(1 << 15)
#define MII_MASK_MLNKFAIL		(1 << 14)
#define MII_MASK_MLOSSSYN		(1 << 13)
#define MII_MASK_MCWRD			(1 << 12)
#define MII_MASK_MSSD			(1 << 11)
#define MII_MASK_MESD			(1 << 10)
#define MII_MASK_MRPOL			(1 << 9)
#define MII_MASK_MJAB			(1 << 8)
#define MII_MASK_MSPDDT			(1 << 7)
#define MII_MASK_MDPLDT			(1 << 6)

/*****************************
 * special debug condition
 */
//#define DEBUG0
//#define DEBUG1

#if defined(DEBUG1)
#define DBG1	if (1) printf
#else
#define DBG1	if (0) printf
#endif

#if defined(DEBUG0)
#define DBG0	if (1) printf
#else
#define DBG0	if (0) printf
#endif

/*
 * retry count
 */
#define MAX_MMU_CMD_RETRY	(96)

/*********************************************************************
 * board dependent definitions
 */

/*********************************************************************
 * lan91c111 dependent definitions
 */
#ifndef LAN91C111_ADDR
#define LAN91C111_ADDR 0 /* will cause run-time exception */
#endif
static LAN91C111 *lan91c111 = (LAN91C111 *)LAN91C111_ADDR;

/************************************************************************
 *      Public variables
 ************************************************************************/

/************************************************************************
 *      Static variables
 ************************************************************************/
static char msg[160] ;

/* Global driver state */
static UINT32 LAN91C111_state = LAN91C111_DRIVER_IS_STOPPED ;

/* User registered receive handler */
static UINT32 (*usr_receive)( UINT32 length, UINT8 *data ) = NULL ;

/* Device context per minor device for this driver */
t_LAN91C111_device   minor_device[LAN91C111_MINOR_DEVICE];

/************************************************************************
 *      Static function prototypes, local helper functions
 ************************************************************************/

/************************************************************************
 *      Implementation : Static functions
 ************************************************************************/

/************************************************************************
 *      Implementation : Local helper functions
 ************************************************************************/

/*********************************************************************
 * lan91c111 dependent functions
 */
#define MDOE (1<<3)
#define MCLK (1<<2)
#define MDI  (1<<1)
#define MDO  (1<<0)

static void mdoSet (UINT16 org)
{
	lan91c111->MGMT_3 = (org | MDOE | MDO);/* MDO = 1 */
	lan91c111->MGMT_3 = (org | MDOE | MCLK | MDO);/* MCLK=1 */
	sys_wait_ms(1);
	lan91c111->MGMT_3 = (org );					/* MCLK=0 */
	sys_wait_ms(1);
}

static void mdoClear (UINT16 org)
{
	lan91c111->MGMT_3 = (org | MDOE);		/* MDO = 0 */
	lan91c111->MGMT_3 = (org | MDOE | MCLK );		/* MCLK=1 */
	sys_wait_ms(1);
	lan91c111->MGMT_3 = (org );					/* MCLK=0 */
	sys_wait_ms(1);
}

static INT32 mdi (UINT16 org)
{
	INT32 bit;
	lan91c111->MGMT_3 = (org | MCLK );		/* MCLK=1 */
	sys_wait_ms(1);
	bit = (lan91c111->MGMT_3 & MDI) ? 1 : 0;
	lan91c111->MGMT_3 = (org );					/* MCLK=0 */
	sys_wait_ms(1);
	return (bit);
}

static void miiWrite (UINT16 phy, UINT16 reg, UINT16 data)
{
	INT32 i;
	UINT16 org, bank;

	/* preserve current bank */
	bank = lan91c111->BANK;
	select(BANK_3);

	org = lan91c111->MGMT_3 & 0xFFF0;

	/* 32 bits of IDLE */
	for (i = 0; i <= 32; ++i)
		mdoSet(org);

	/* ST[1:0]=01 for start */
		mdoClear(org);
		mdoSet(org);

	/* OP[1:0]=01 for write */
		mdoClear(org);
		mdoSet(org);

	/* PHYAD[4:0] */
	for (i = 4; i >= 0; --i)
		if (phy & (1<<i)) mdoSet(org); else mdoClear(org);

	/* REGAD[4:0] */
	for (i = 4; i >= 0; --i)
		if (reg & (1<<i)) mdoSet(org); else mdoClear(org);

	/* TA[1:0] */
		mdoSet(org);
		mdoClear(org);

	/* DATA[15:0] */
	for (i = 15; i >= 0; --i)
		if (data & (1<<i)) mdoSet(org); else mdoClear(org);

	/* 32 bits of IDLE */
	for (i = 0; i <= 32; ++i)
		mdoSet(org);

	/* restore bank */
	lan91c111->BANK = bank;
}

static UINT16 miiRead (UINT16 phy, UINT16 reg)
{
	INT32 i;
	UINT16 org, bank;
	UINT16 data = 0x0000;

	/* preserve current bank */
	bank = lan91c111->BANK;
	select(BANK_3);

	org = lan91c111->MGMT_3 & 0xFFF0;

	/* 32 bits of IDLE */
	for (i = 0; i <= 32; ++i)
		mdoSet(org);

	/* ST[1:0]=01 for start */
		mdoClear(org);
		mdoSet(org);

	/* OP[1:0]=10 for read */
		mdoSet(org);
		mdoClear(org);

	/* PHYAD[4:0] */
	for (i = 4; i >= 0; --i)
		if (phy & (1<<i)) mdoSet(org); else mdoClear(org);

	/* REGAD[4:0] */
	for (i = 4; i >= 0; --i)
		if (reg & (1<<i)) mdoSet(org); else mdoClear(org);

	/* TA[1:0] */
		//mdoSet(org); HIGH Z turnaround time
		mdoClear(org);

	/* DATA[15:0] */
	for (i = 15; i >= 0; --i)
		data |= (mdi(org) << i);

	/* 32 bits of IDLE */
	for (i = 0; i <= 32; ++i)
		mdoSet(org);

	/* restore bank */
	lan91c111->BANK = bank;

	return (data);
}

/***********************************************************************
 * MMU related functions
 ***********************************************************************/
static INT32 issue_mmu_command(INT32 mmu_command, INT32 wait)
{
	select(BANK_2);
	lan91c111->MMU_2 = mmu_command;

	/* Wait for MMU command to complete */
	if (wait == MMU_WAIT)
	{
		INT32 loop = MAX_MMU_CMD_RETRY;
		while(loop--)
		{
			asm(" sync");
			if(!(lan91c111->MMU_2 & MMU_BUSY)) return (OK);
		}
		return (ERROR_LAN_DEVICE_BUSY);
	}
	return (OK);
}

static UINT32 txStats(t_LAN91C111_device *pdevice, UINT16 status)
{
	UINT32 ret_value = OK;

	/* Check for frame abort */
 	if ((status /*= lan91c111->EPH_0*/) & (ESR_TXUNRN | ESR_LOST_CARR | ESR_LOTCAL |\
					   ESR_SQET | ESR_16COL | ESR_MULT_COL | ESR_SNGL_COL))
	{
		ret_value = ERROR_LAN_TXM_ERROR;
		pdevice->status.tx_errors++;
		if (status & ESR_TXUNRN)
			pdevice->status.tx_under_run++;

		if (status & ESR_LOST_CARR)
			pdevice->status.tx_lost_carrier++;

		if (status & ESR_LOTCAL)
			pdevice->status.tx_late_collision++;
			
		if (status & ESR_SQET)
			pdevice->status.tx_signal_quality++;

		if (status & ESR_16COL)
			pdevice->status.tx_16_collisions++;

		if (status & ESR_MULT_COL)
			pdevice->status.tx_multiple_collisions++;
	}
	return (ret_value);
}

static int allocTx(t_LAN91C111_device *pdevice)
{
	UINT8 alloc_result;

	DBG0(">>ALLOC!\n");

	issue_mmu_command(MMU_CMD_TX_ALLOC, MMU_WAIT);
	//select(BANK_2);
	alloc_result = lan91c111->PNRHI_2;
	if (alloc_result & TX_ALLOCATION_FAILED)
	{
		//no packet alloced! issue_mmu_command(MMU_CMD_RELEASE_PACKET, MMU_NOWAIT);
		//issue_mmu_command(MMU_CMD_TX_FIFO_RESET, MMU_NOWAIT);
		DBG0("Failed#1\n");
		return (ERROR_LAN_DEVICE_BUSY);
	}
	return (OK);
}

static INT32 setup_phy_pre(void)
{
	int i;
	/* disable all interrupts */
	select(BANK_2);
	lan91c111->INTMASKHI_2 = 0;
	select(BANK_1);
	/* set up configuration register(0) */
	lan91c111->CONFIG_1 = (CFG_EPHPOWEREN | CFG_NOWAIT); 
	/* initialize Bank1 control register */
	lan91c111->CONTROL_1 = (CTL_RX_BAD | CTL_AUTO | CTL_LE_EN | CTL_CR_EN | CTL_TE_EN);
	/* zero clear the multi-cast table */
	select(BANK_3);
	lan91c111->MT01_3 = lan91c111->MT23_3 = lan91c111->MT45_3 = lan91c111->MT67_3 = 0;

	select(BANK_0);
	/* set up Rx control register */
	lan91c111->RCR_0 = (RCR_RXEN | RCR_STRIP_CRC /*| RCR_PRMS*/);
	/* set up Tx control register */
	lan91c111->TCR_0 = (TCR_SWFDUP | TCR_PAD_EN | TCR_TXEN);
	/* start auto neg. LED-A: Link, LED-B: rx or rx activity */
	lan91c111->RPCR_0 = (RPCR_ANEG | LEDA_LINK | LEDB_ACTIVITY);
	/* Reset PHY */
	miiWrite(0, 0, 0x8000);
	for (i = 0; i < 50; ++i)
	{
		if ((miiRead(0,0) & 0x8000) == 0x0000)
			break;
	}
	/* Take PHY out of isolation; enable the PHY, ANEG */
	miiWrite(0, 0, 0x1000);

	return (OK);
}

/************************************************************************
 *
 *                          allocate_buffers
 *  Description :
 *  -------------
 *     This routine allocates memory for:
 *
 *     - Receive buffers
 *     - Transmit buffer
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  'pdevice',     IN,    reference for this device  context
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *
 *
 *
 ************************************************************************/
static
INT32 allocate_buffers( t_LAN91C111_device *pdevice )  
{
	INT32 i;
	UINT8 *buf;

	memset(pdevice, 0 , sizeof (t_LAN91C111_device));

	buf = (UINT8 *)((UINT32)(pdevice->rx_buffer_pool + 31) & ~0x0000001f);
	for (i = 0; i < RX_CIRCULAR_BUFFERS; ++i)
	{
		pdevice->rx_buffer_addr[i] = (UINT32)KSEG0(&buf[(i * RX_BUFF_SIZE)]);
	}
	pdevice->NextRxBuffer = 0;
	return( OK );
}

static INT32 MII_status(t_LAN91C111_device *pdevice)
{
	UINT32 ret_value = OK;
	UINT16 data;
	if ((data = miiRead(0,MII_ADVERTISEMENT)) & MII_ADVERTISEMENT_ACK)
	{
		DBG1("PHY is ready...%x\n", data);
		if ((data = miiRead(0,MII_STATUS)) & MII_STATUS_LINK)
			DBG1("Link is up...%x\n", data);
		else
			DBG1("No Link...%x\n", data);
	}
	else
	{
		DBG1("PHY auto-neg failed! %x \n", data);
		ret_value = ERROR_LAN_DEVICE_NOTRDY;
	}
	return (ret_value);

⌨️ 快捷键说明

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