www.pudn.com > s3c2410bsp_ce400_v100.zip > cs8900dbg.c


/****************************************************************************** 
 * 
 * System On Chip(SOC) 
 * 
 * Copyright (c) 2002 Software Center, Samsung Electronics, Inc. 
 * All rights reserved. 
 * 
 * This software is the confidential and proprietary information of Samsung  
 * Electronics, Inc("Confidential Information"). You Shall not disclose such  
 * Confidential Information and shall use it only in accordance with the terms  
 * of the license agreement you entered into Samsung. 
 * 
 *----------------------------------------------------------------------------- 
 * 
 *	S3C2410 BSP  
 * 
 * cs8900dbg.c : EBOOT CS8900 ETHDBG Driver Main Src 
 * 
 * @author		zartoven@samsung.com (SOC, SWC, SAMSUNG Electronics) 
 * 
 * @date		2002/04/09 
 *  
 * Log: 
 *		2002/04/09	Start 
 *       
 ****************************************************************************** 
 */ 
     
#include  
#include  
#include "cs8900dbg.h" 
 
#define PUBLIC 
#define PRIVATE						static 
 
#define IOREAD(o)					((USHORT)*((volatile USHORT *)(dwEthernetIOBase + (o)))) 
#define IOWRITE(o, d)				*((volatile USHORT *)(dwEthernetIOBase + (o))) = (USHORT)(d) 
 
#define MEMREAD(o)					((USHORT)*((volatile USHORT *)(dwEthernetMemBase + (o)))) 
#define MEMWRITE(o, d)				*((volatile USHORT *)(dwEthernetMemBase + (o))) = (USHORT)(d) 
 
#define DBGMSG						EdbgOutputDebugString 
#define MAX_COUNT					0x100000 
 
#define CS8900DBG_PROBE				(1 << 0) 
 
PRIVATE DWORD dwEthernetIOBase; 
PRIVATE DWORD dwEthernetMemBase; 
 
#define CS8900_MEM_MODE 
 
#ifdef	CS8900_MEM_MODE 
 
#define READ_REG1					ReadReg 
#define READ_REG2					MEMREAD 
 
#define WRITE_REG1					WriteReg 
#define WRITE_REG2					MEMWRITE 
 
#else 
 
#define READ_REG1					ReadReg 
#define READ_REG2					ReadReg 
 
#define WRITE_REG1					WriteReg 
#define WRITE_REG2					WriteReg 
 
#endif 
 
PRIVATE	BOOL bIsPacket; 
 
PRIVATE USHORT  
ReadReg(USHORT offset) 
{ 
	IOWRITE(IO_PACKET_PAGE_POINTER, offset); 
	return IOREAD(IO_PACKET_PAGE_DATA_0); 
} 
 
PRIVATE void  
WriteReg(USHORT offset, USHORT data) 
{ 
	IOWRITE(IO_PACKET_PAGE_POINTER, offset); 
	IOWRITE(IO_PACKET_PAGE_DATA_0 , data); 
} 
 
PRIVATE BOOL  
Probe(DWORD iobase, DWORD membase) 
{ 
	BOOL r = FALSE; 
 
	DBGMSG("::: CS8900 Probe()\n"); 
 
	dwEthernetIOBase  = iobase; 
	dwEthernetMemBase = membase; 
 
	do  
	{ 
		if (IOREAD(IO_PACKET_PAGE_POINTER) != CS8900_SIGNATURE) 
		{ 
			DBGMSG("Signature Error\n"); 
			break; 
		} 
											/* Check the EISA registration number.	*/ 
		if (READ_REG1(PKTPG_EISA_NUMBER) != CS8900_EISA_NUMBER) 
		{ 
			DBGMSG("Eisa Number Error\n"); 
			break; 
		} 
											/* Check the Product ID.				*/ 
		if ((READ_REG1(PKTPG_PRDCT_ID_CODE) & CS8900_PRDCT_ID_MASK) 
			!= CS8900_PRDCT_ID) 
		{ 
			DBGMSG("Product ID Error\n"); 
			break; 
		} 
	    
		DBGMSG("CS8900 is Detected..\n"); 
		r = TRUE; 
	} while (0); 
 
	return r; 
} 
 
PRIVATE BOOL  
Reset(void) 
{ 
	BOOL r = FALSE; 
	USHORT dummy; 
	int i; 
											/* Set RESET bit of SelfCTL register.	*/ 
	do  
	{ 
		WRITE_REG1(PKTPG_SELF_CTL, SELF_CTL_RESET | SELF_CTL_LOW_BITS); 
 
								/* Wait until INITD bit of SelfST register is set.	*/ 
		for (i = 0; i < MAX_COUNT; i++) 
		{ 
			dummy = READ_REG1(PKTPG_SELF_ST); 
			if (dummy & SELF_ST_INITD) break; 
		} 
 
		if (i >= MAX_COUNT) 
		{ 
			DBGMSG("Reset failed (SelfST) \n"); 
			break; 
		} 
 
						/* Wait until SIBUSY bit of SelfST register is cleared.		*/ 
		for (i = 0; i < MAX_COUNT; i++) 
		{ 
			dummy = READ_REG1(PKTPG_SELF_ST); 
			if ((dummy & SELF_ST_SIBUSY) == 0) break; 
		} 
 
		if (i >= MAX_COUNT) 
		{ 
			DBGMSG("Reset failed (SIBUSY) \n"); 
			break; 
		} 
		r = TRUE; 
		DBGMSG("Reset Success!!\n"); 
 
	} while (0); 
 
	return r; 
} 
 
 
PRIVATE void  
EnableIRQ(void) 
{ 
	USHORT temp; 
						/* If INTERRUPT_NUMBER is 0,							*/ 
						/*	Interrupt request will be generated from INTRQ0 pin */ 
	WRITE_REG2(PKTPG_INTERRUPT_NUMBER, INTERRUPT_NUMBER); 
 
	temp = READ_REG2(PKTPG_BUS_CTL) | BUS_CTL_ENABLE_IRQ; 
 
	WRITE_REG2(PKTPG_BUS_CTL, temp); 
 
	temp = READ_REG2(PKTPG_LINE_CTL) | LINE_CTL_RX_ON | LINE_CTL_TX_ON; 
	WRITE_REG2(PKTPG_LINE_CTL,temp); 
} 
 
 
PRIVATE BOOL  
Init(USHORT *mac) 
{ 
	USHORT temp; 
 
#ifdef CS8900_MEM_MODE 
 
	WRITE_REG1(PKTPG_MEMORY_BASE_ADDR     , (USHORT)(dwEthernetMemBase & 0xffff)); 
	WRITE_REG1(PKTPG_MEMORY_BASE_ADDR + 2 , (USHORT)(dwEthernetMemBase >> 16   )); 
	WRITE_REG1(PKTPG_BUS_CTL              ,  BUS_CTL_MEMORY_E | BUS_CTL_LOW_BITS); 
 
#endif 
 
	temp = READ_REG2(PKTPG_LINE_CTL) | LINE_CTL_10_BASE_T | LINE_CTL_MOD_BACKOFF; 
	WRITE_REG2(	PKTPG_LINE_CTL, temp); 
						 
	WRITE_REG2(PKTPG_RX_CFG, RX_CFG_RX_OK_I_E | RX_CFG_LOW_BITS); 
 
	WRITE_REG2(PKTPG_RX_CTL, 
		            RX_CTL_RX_OK_A | RX_CTL_IND_ADDR_A | RX_CTL_BROADCAST_A | RX_CTL_LOW_BITS); 
 
	WRITE_REG2(PKTPG_INDIVISUAL_ADDR + 0, *mac++); 
	WRITE_REG2(PKTPG_INDIVISUAL_ADDR + 2, *mac++); 
	WRITE_REG2(PKTPG_INDIVISUAL_ADDR + 4, *mac  ); 
 
	WRITE_REG2(PKTPG_TX_CFG, TX_CFG_LOW_BITS); 
 
	EnableIRQ(); 
 
	DBGMSG("CS8900_Init OK.\n"); 
	return TRUE; 
} 
 
PRIVATE int 
RcvPkt(BYTE *pbData, DWORD dwLength) 
{ 
					/* use int rather than short for the reason of performance	*/ 
	DWORD   length; 
	DWORD   rlen = 0; 
	USHORT *bp; 
	USHORT	data; 
 
														/* Discard RxStatus		*/ 
	data   = IOREAD(IO_RX_TX_DATA_0); 
												/* Read the frame's length.		*/ 
	length = IOREAD(IO_RX_TX_DATA_0); 
 
	if (length > dwLength) length = 0; 
 
	bp    = (USHORT *)pbData; 
 
	rlen = length; 
 
	while (rlen) 
	{ 
		data = IOREAD(IO_RX_TX_DATA_0); 
 
		if (rlen == 1) 
		{ 
			*((BYTE *)bp) = (BYTE)data; 
			rlen--; 
		} 
		else 
		{ 
			*bp++ = data; 
			rlen -= 2; 
		} 
	} 
 
	return length; 
} 
 
 
PRIVATE USHORT  
TransmitPkt(BYTE *pbData, USHORT slen) 
{ 
	USHORT * bp; 
	USHORT   data; 
	DWORD	 i; 
 
	/* Send Command */ 
	IOWRITE(IO_TX_CMD, TX_CMD_START_ALL | TX_CMD_LOW_BITS); 
	IOWRITE(IO_TX_LENGTH, slen); 
 
	/* Wait			*/ 
	for (i = 0; i < MAX_COUNT; i++) 
	{ 
		data = READ_REG2(PKTPG_BUS_ST); 
		if (data & BUS_ST_RDY_4_TX_NOW) break; 
	}  
 
	if (i >= MAX_COUNT) return 1; 
 
	bp = (USHORT *)pbData; 
 
	while (slen) 
	{ 
		IOWRITE(IO_RX_TX_DATA_0, *bp++); 
		slen--; 
 
		if (slen) slen--; 
	} 
 
	return 0; 
} 
 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
 
PUBLIC BOOL 
CS8900DBG_Init(DWORD iobase, DWORD membase, USHORT MacAddr[3]) 
{ 
	BOOL r = FALSE; 
 
	bIsPacket = FALSE; 
     
    DBGMSG("::: CS8900DBG_Init\r\n"); 
     
    DBGMSG("CS8900 Mac Address: %B:%B:%B:%B:%B:%B\r\n", 
			  MacAddr[0] & 0x00FF, MacAddr[0] >> 8, 
			  MacAddr[1] & 0x00FF, MacAddr[1] >> 8, 
			  MacAddr[2] & 0x00FF, MacAddr[2] >> 8); 
    do 
	{ 
		if (!Probe(iobase, membase)) break; 
		if (!Reset())				 break; 
		if (!Init(MacAddr))			 break; 
 
		r = TRUE; 
	} while (0); 
	return r; 
} 
 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
 
PUBLIC BOOL 
CS8900DBG_IsReceivedPacket(void) 
{ 
	USHORT event; 
	BOOL   r = FALSE; 
 
	event = IOREAD(IO_ISQ);			 
 
	if ( ((event & ISQ_REG_NUM   )    == REG_NUM_RX_EVENT ) && 
		 ((event & RX_EVENT_RX_OK)    == RX_EVENT_RX_OK   ) && 
		 ((event & RX_EVENT_IND_ADDR) | (event & RX_CTL_BROADCAST_A)))  
	{ 
		r = bIsPacket = TRUE; 
	} 
	else 
		bIsPacket = FALSE; 
 
	return r; 
} 
 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
PUBLIC UINT16 
CS8900DBG_GetFrame(BYTE *pbData, UINT16 *pwLength) 
{ 
    UINT16 r = 0; 
	 
	if (!bIsPacket)  
		CS8900DBG_IsReceivedPacket(); 
 
	if (bIsPacket)  
	{ 
		bIsPacket = FALSE; 
		r = RcvPkt(pbData, *pwLength); 
	} 
 
	return r; 
} 
 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
PUBLIC UINT16  
CS8900DBG_SendFrame( BYTE *pbData, DWORD dwLength )  
{ 
	return  
		TransmitPkt(pbData, (UINT16)dwLength); 
} 
 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
PUBLIC BOOL 
CS8900DBG_ReInit(DWORD iobase, DWORD membase) 
{ 
	DBGMSG("::: CS8900DBG_ReInit()\n"); 
 
	bIsPacket = FALSE; 
 
	dwEthernetIOBase  = iobase; 
	dwEthernetMemBase = membase; 
 
	return TRUE; 
}