📄 mac8947.c
字号:
/* * 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 + -