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

📄 mac8947.c

📁 source code of armboot for s3c4510
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cirrus Logic CS8900A Ethernet * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> * * Copyright (C) 1999 Ben Williamson <benw@pobox.com> * * See file CREDITS for list of people who contributed to this * project. * * This program is loaded into SRAM in bootstrap mode, where it waits * for commands on UART1 to read and write memory, jump to code etc. * A design goal for this program is to be entirely independent of the * target board.  Anything with a CL-PS7111 or EP7211 should be able to run * this code in bootstrap mode.  All the board specifics can be handled on * the host. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "armboot.h"#include "command.h"#include "net.h"#include "s5n8947.h"#include "mac8947.h"#include "log.h"//add by hill 20070919#undef TEST_MAC_SEND#ifdef CONFIG_S5N8947#if (CONFIG_COMMANDS & CFG_CMD_NET)API_DEVICE			api_Mac_dev;#ifdef SD16BIT	//?? by maveric 2002.10.2RECEIVE_FRAME_DESC	rx_buff_desc[RX_FD_NUM*2];TRANSMIT_FRAME_DESC	tx_buff_desc[TX_FD_NUM*2];#elseRECEIVE_FRAME_DESC	rx_buff_desc[RX_FD_NUM];TRANSMIT_FRAME_DESC	tx_buff_desc[TX_FD_NUM];#endifFD_RX_FRAME_DATA	rx_framebuff_addr[RX_FD_NUM];#ifdef SD16BITunsigned long MACFD16Set(char *address){	unsigned int TmpAddr;	TmpAddr = (unsigned int)address;	TmpAddr &=0xffffff00;	TmpAddr = TmpAddr + 0x100;	return(TmpAddr);}#endifvoid InitEtherApi(bd_t *bd){	api_init(bd, &api_Mac_dev);}void eth_halt( void ){	api_MacIntDisable(&api_Mac_dev);	api_MacHWStop(&api_Mac_dev);	api_MacHWReset(&api_Mac_dev);	api_MacBuffFree(&api_Mac_dev);}int eth_init( bd_t *bd ){	api_MacBuffInit(&api_Mac_dev);		api_MacHWInit(&api_Mac_dev);		api_MacHWStart(&api_Mac_dev);	    	return 0;}/* Get a data block via Ethernet */extern int eth_rx(void){	api_MacRcv(&api_Mac_dev);    /* Pass the packet up to the protocol layers. */    /*NetReceive(NetRxPackets[0], rxlen);*/    return 0;}/* Send a data block via Ethernet. */extern int eth_send(volatile void *packet, int length){	api_MacSend(&api_Mac_dev, (ulong)packet, length);    return 0;}/***************************//* Sub Function for driver *//***************************//********************************************************************************* api_MacHWReset - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacHWReset(API_DEVICE *api_Mac_dev){	uBDMARXCON bdmaRxCon;	uBDMATXCON bdmaTxCon;	uBDMARXLSZ bdmaRxLsz;	uMACCON macCon;	ulong	BdmaAddr = api_Mac_dev->BdmaAddr;	ulong	MacAddr  = api_Mac_dev->MacAddr;	*(ulong *)(&bdmaRxCon) = 0;	*(ulong *)(&bdmaTxCon) = 0;	*(ulong *)(&bdmaRxLsz) = 0;	*(ulong *)(&macCon) = 0;			/*Init mac phy */	MAC_PHY_INIT();	bdmaRxCon.rxCon_reg.reset = 1;	REG_OUT_LONG (BdmaAddr, BDMARXCON, bdmaRxCon.rxCon_resetval);		bdmaTxCon.txCon_reg.reset = 1;	REG_OUT_LONG (BdmaAddr, BDMATXCON, bdmaTxCon.txCon_resetval);		bdmaRxLsz.rxLsz_reg.bdmaRxMaxSize = END_BUFSIZ;	REG_OUT_LONG (BdmaAddr, BDMARXLSZ, bdmaRxLsz.rxLsz_resetval);	macCon.macCon_reg.swReset = 1;	macCon.macCon_reg.mii_off = ETH_PHY_SELECT;		/* MII ON or 7-Wire ON */		REG_OUT_LONG (MacAddr, MACCON, macCon.macCon_resetval);	api_Mac_dev->status = HW_RESET_DONE;			return OK;}/*********************************************************************************    api_MacBuffInit - Initialize TX and RX FD lists*    Make a circular list of Rx and TX frame descriptors and buffers.*    Two global variables gpReceiveFrameDescStart and gpTransmitFrameDescStart *    stores the pointer to the start of the list.  BDMA TX/RX PTR registers are *    also initialized with the start of the appropriate list.*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacBuffInit(API_DEVICE *api_Mac_dev){	STATUS 					status = OK;	    int 						count;    RECEIVE_FRAME_DESC* 		pReceiveFrameDesc;    TRANSMIT_FRAME_DESC* 	pTransmitFrameDesc;    RECEIVE_FRAME_DESC* 		pPrevReceiveFrameDesc=0;    TRANSMIT_FRAME_DESC* 	pPrevTransmitFrameDesc=0;    ulong						pBdmaAddr=api_Mac_dev->BdmaAddr;    char*						pReceiveFramebuff;    ulong						pDummy;	#ifdef SD16BIT  	char*					pTmpFrameDesc;	pTmpFrameDesc = &rx_buff_desc[0]; 	pReceiveFrameDesc =	MACFD16Set(pTmpFrameDesc);#endif    	/*Init Rx Fd */	for(count = 0; count < RX_FD_NUM; count++)	{#ifndef SD16BIT		pReceiveFrameDesc = (RECEIVE_FRAME_DESC *)&(rx_buff_desc[count]);#endif		pDummy = (ulong)pReceiveFrameDesc;		pDummy |= NON_CACHE_REGION;		pReceiveFrameDesc = (RECEIVE_FRAME_DESC *)pDummy;#if 0		printf("pReceiveFrameDesc[%d] = 0x%x\n",count,pReceiveFrameDesc);	//for debug by maveric 2002.10.2#endif	//	pReceiveFramebuff = (ulong)&(rx_framebuff_addr[count]);		pReceiveFramebuff = (char *)&(rx_framebuff_addr[count]);				(pReceiveFrameDesc->rxFrameData).frameDataPtr = (ulong)pReceiveFramebuff;		(pReceiveFrameDesc->rxFrameData).frameDataPtr |= NON_CACHE_REGION;				(pReceiveFrameDesc->rxFrameData).o_bit = 1;/*owner : BDMA*/		*(ulong *) (&pReceiveFrameDesc->rxStatusLength) = 0;		pReceiveFrameDesc->nextRxFrameDesc = NULL;		if (count == 0)		{			(api_Mac_dev->gpReceiveFrameDescStart) = pReceiveFrameDesc;						REG_OUT_LONG (pBdmaAddr, BDMARXPTR, *(ulong *) (&pReceiveFrameDesc));		}		else		{			pPrevReceiveFrameDesc->nextRxFrameDesc = pReceiveFrameDesc;		}		if (count == (RX_FD_NUM - 1))		{			pReceiveFrameDesc->nextRxFrameDesc = (api_Mac_dev->gpReceiveFrameDescStart);		}		pPrevReceiveFrameDesc = pReceiveFrameDesc;#ifdef SD16BIT		pReceiveFrameDesc++;#endif	}/* end of for loop*/#ifdef SD16BIT	pTmpFrameDesc = &tx_buff_desc[0]; 	pTransmitFrameDesc =	MACFD16Set(pTmpFrameDesc);#endif    /*Init Tx Fd */	for(count = 0; count < TX_FD_NUM; count++)	{#ifndef SD16BIT		pTransmitFrameDesc = (TRANSMIT_FRAME_DESC *)&(tx_buff_desc[count]);#endif		pDummy = (ulong)pTransmitFrameDesc;		pDummy |= NON_CACHE_REGION;		pTransmitFrameDesc = (TRANSMIT_FRAME_DESC *)pDummy;		(pTransmitFrameDesc->txFrameData).frameDataPtr = 0;		(pTransmitFrameDesc->txFrameData).o_bit = 0;/*owner : CPU*/		*(ulong *) (&pTransmitFrameDesc->txControl) = 0;		pTransmitFrameDesc->nextTxFrameDesc = NULL;		if (count == 0)		{			(api_Mac_dev->gpTransmitFrameDescStart) = pTransmitFrameDesc;			REG_OUT_LONG (pBdmaAddr, BDMATXPTR, *(ulong *) (&pTransmitFrameDesc));		}		else		{			pPrevTransmitFrameDesc->nextTxFrameDesc = pTransmitFrameDesc;		}		if (count == (TX_FD_NUM - 1))		{			pTransmitFrameDesc->nextTxFrameDesc = (api_Mac_dev->gpTransmitFrameDescStart);		}		pPrevTransmitFrameDesc = pTransmitFrameDesc;#ifdef SD16BIT		pTransmitFrameDesc++;#endif	}/* end of for loop */			api_Mac_dev->buffInitialized = INIT_DONE;	api_Mac_dev->status = BUFF_INIT_DONE;			return status;}/*********************************************************************************	api_MacBuffFree - Free the allocated TX and RX FD lists and buffers*	This function frees all the allocated TX and RX FDs and the associated*	buffers** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacBuffFree(API_DEVICE *api_Mac_dev){	STATUS status = OK;		api_Mac_dev->buffInitialized = NOT_INIT_YET;	api_Mac_dev->status = BUFF_FREE_DONE;			return status;}/********************************************************************************** RETURNS: OK or ERROR return status why..** SEE ALSO:*/int api_MacHWInit(API_DEVICE *api_Mac_dev){	STATUS status = OK;	uBDMARXCON 	bdmaRxCon;	uBDMATXCON 	bdmaTxCon;	uMACCON 	macCon;	uCAMCON 	camCon;	uMACTXCON 	macTxCon;	uMACRXCON 	macRxCon;	uCAMEN 		camEn;	ulong 		count;	uchar 		*pAddr;	ulong		pBdmaAddr=api_Mac_dev->BdmaAddr;	ulong		pMacAddr=api_Mac_dev->MacAddr;	/* init MACCON register */	*(ulong *)(&macCon) = 0;	macCon.macCon_reg.mii_off = ETH_PHY_SELECT;	REG_OUT_LONG(pMacAddr, MACCON, macCon.macCon_resetval);		/* init BDMA TXRX PTR registers */	REG_OUT_LONG(pBdmaAddr, BDMARXPTR, *(ulong *) (&(api_Mac_dev->gpReceiveFrameDescStart))); 	REG_OUT_LONG(pBdmaAddr, BDMATXPTR, *(ulong *) (&(api_Mac_dev->gpTransmitFrameDescStart))); 	/* Copy our MAC address to the first location in address array */	pAddr = (uchar *)(&(api_Mac_dev->addrList[0]));	*(ulong *)pAddr = htonl (*(ulong *)api_Mac_dev->enetAddr);	#if	BIG_ENDIAN	pAddr += 4;	#else	/*LITTLE_ENDIAN*/	pAddr += 6;	#endif	/*BIG_ENDIAN*/	*(ushort *)pAddr = htons (*(ushort *)(api_Mac_dev->enetAddr+4));	/* Copy the address array into CAM registers */	for (count = 0; count < 32; count++)		REG_OUT_LONG(pBdmaAddr, (CAM_BASE + (count*4)), api_Mac_dev->addrList[count]); 			/* init CAMCON register */	*(ulong *) (&camCon) = 0;		camCon.camCon_reg.broadcastAccept = 1;	camCon.camCon_reg.cmpEnable = 1;			REG_OUT_LONG(pMacAddr, CAMCON, camCon.camCon_resetval); 		/* init CAMEN register.  Set bits for our MAC address and all	 * multicast addresses	 */	api_Mac_dev->mcastAddrCount = 21;	*(ulong *)(&camEn) = 0;	for (count = 0; count <= api_Mac_dev->mcastAddrCount; count++)	{		camEn.camen_reg.camEnable |= (0x1<<count);	}	REG_OUT_LONG(pMacAddr, CAMEN, camEn.camen_resetval); 		/* init BDMARXCON register */	*(ulong *) (&bdmaRxCon) = 0;	/* <<Attention>> S5N8946=0, S5N8947=0x0F */	//bdmaRxCon.rxCon_reg.burstSize = 0x0F;		bdmaRxCon.rxCon_reg.burstSize = 0x1f;//change by hill 20070919		bdmaRxCon.rxCon_reg.stop_skipFrame = 1;	bdmaRxCon.rxCon_reg.memAddrsInc_Dec = 1;#if	BIG_ENDIAN	bdmaRxCon.rxCon_reg.big_LittleEndian = 0; #else	/*if BIG_ENDIAN*/	bdmaRxCon.rxCon_reg.big_LittleEndian = 1; #endif	/*if BIG_ENDIAN*/	bdmaRxCon.rxCon_reg.wordAlign = 0;	bdmaRxCon.rxCon_reg.reset = 0;	REG_OUT_LONG(pBdmaAddr, BDMARXCON, bdmaRxCon.rxCon_resetval); 		/* init MACRXCON register */	*(ulong *)(&macRxCon) = 0;	macRxCon.macRxCon_reg.stripCRCVal = 1;	REG_OUT_LONG(pMacAddr, MACRXCON, macRxCon.macRxCon_resetval); 		/* init BDMATXCON register */	*(ulong *)(&bdmaTxCon) = 0;	//bdmaTxCon.txCon_reg.burstSize = 15;	bdmaTxCon.txCon_reg.burstSize = 31;//change by hill 20070919		bdmaTxCon.txCon_reg.stop_skipFrame = 1;	//bdmaTxCon.txCon_reg.macTxStartLevel = 6;	bdmaTxCon.txCon_reg.macTxStartLevel = 4;//modify by hill 20070919	REG_OUT_LONG(pBdmaAddr, BDMATXCON, bdmaTxCon.txCon_resetval); 		/* init MACTXCON register */	*(ulong *)(&macTxCon) = 0; 		macTxCon.macTxCon_reg.enableUnderRun = 1;	macTxCon.macTxCon_reg.enableDeferral = 1;	macTxCon.macTxCon_reg.enableNoCarrier = 1;	macTxCon.macTxCon_reg.enableExcessCollision = 1;	macTxCon.macTxCon_reg.enableLateCollison = 1;	macTxCon.macTxCon_reg.enableTxParity = 1;	macTxCon.macTxCon_reg.fastBackOff = 1;		REG_OUT_LONG(pMacAddr, MACTXCON, macTxCon.macTxCon_resetval); 		api_Mac_dev->status = HW_INIT_DONE;		return status;}/********************************************************************************* api_MacHWStart - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacHWStart(API_DEVICE *api_Mac_dev){	STATUS status = OK;			uBDMARXCON bdmaRxCon;	uMACRXCON macRxCon;    	ulong	pBdmaAddr=api_Mac_dev->BdmaAddr;	ulong	pMacAddr=api_Mac_dev->MacAddr;	/* init BDMARXCON register */	REG_IN_LONG(pBdmaAddr, BDMARXCON, *(ulong *) (&bdmaRxCon)); 	bdmaRxCon.rxCon_reg.recvFrameIntrEnb = 1;	bdmaRxCon.rxCon_reg.nullListIntrEnb = 1;       bdmaRxCon.rxCon_reg.notOwnerIntrEnb = 1;	bdmaRxCon.rxCon_reg.enable = 1 ;	REG_OUT_LONG(pBdmaAddr, BDMARXCON, bdmaRxCon.rxCon_resetval); 		/* init MACRXCON register */	REG_IN_LONG(pMacAddr, MACRXCON, *(ulong *) (&macRxCon)); 	macRxCon.macRxCon_reg.receiveEnable = 1;	REG_OUT_LONG(pMacAddr, MACRXCON, macRxCon.macRxCon_resetval); 	api_Mac_dev->status = HW_START_STATUS;			return status;}/********************************************************************************* api_MacHWStop - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacHWStop (API_DEVICE *api_Mac_dev){	STATUS status = OK;			uBDMARXCON 	bdmaRxCon;	uBDMATXCON 	bdmaTxCon;	uMACCON 	macCon;    ulong		BdmaAddr=api_Mac_dev->BdmaAddr;	ulong		MacAddr=api_Mac_dev->MacAddr;	REG_IN_LONG(BdmaAddr, BDMARXCON, *(ulong *)(&bdmaRxCon)); 	bdmaRxCon.rxCon_reg.enable = 0;	REG_OUT_LONG(BdmaAddr, BDMARXCON, *(ulong *)(&bdmaRxCon)); 	REG_IN_LONG(BdmaAddr, BDMATXCON, *(ulong *)(&bdmaTxCon)); 	bdmaTxCon.txCon_reg.enable = 0;	REG_OUT_LONG(BdmaAddr, BDMATXCON, *(ulong *)(&bdmaTxCon)); 		REG_IN_LONG(MacAddr, MACCON, *(ulong *)(&macCon)); 	macCon.macCon_reg.haltImm  = 1;	REG_OUT_LONG(MacAddr, MACCON, *(ulong *)(&macCon)); 	api_Mac_dev->status = STOP_STATUS;			return status;}/********************************************************************************* api_MacRcv - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */void api_MacRcv(API_DEVICE *api_Mac_dev){	uBDMASTAT 				bdmaStat;	uBDMARXCON 				bdmaRxCon;	RECEIVE_FRAME_DESC*		pReceiveFrameDesc;

⌨️ 快捷键说明

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