www.pudn.com > 440B0-LwIP.zip > MacUtil.c


#include  
 
#include "std.h" 
#include "sysconf.h" 
#include "snds.h" 
#include "isr.h" 
#include "mac.h" 
 
//下面是为协议栈的存在而添加的 
#include "netif.h" 
#include "eth4510if.h" 
 
#include    "OS_CPU.h" 
/* 
#include  
#include  
#include  
 
 
#include "uart.h" 
#include "pollio.h" 
#include "timer.h" 
#include "memory.h" 
#include "iic.h" 
*/ 
 
 
sFrameDescriptor RxFDBaseAddr[MaxRxFrameDescriptors];   // Tx Frame Descriptor 
sMACFrame RxFBABaseAddr[MaxRxFrameData];		// Tx Frame Buffer 
 
sFrameDescriptor TxFDBaseAddr[MaxTxFrameDescriptors];   // Rx Frame Descriptor 
sMACFrame TxFBABaseAddr[MaxTxFrameData];		// Rx Frame Buffer 
 
// Global variables  used for MAC driver 
volatile U32 gMacCon = FullDup ; 
volatile U32 gMacTxCon = EnComp ; 
volatile U32 gMacRxCon = RxEn | StripCRC ;  
volatile U32 gBdmaTxCon = BTxBRST | BTxMSL110 | BTxSTSKO ; 
 
volatile U32 gBdmaRxCon = BRxDIE | BRxEn | BRxLittle | BRxMAINC | BRxBRST | \ 
                          BRxNLIE | BRxNOIE | BRxSTSKO ; 
volatile U32 gCamCon = CompEn | BroadAcc | GroupAcc; 
 
volatile U32 gDuplexValue = 0 ; 
 
volatile U32 gCTxFDPtr, gWTxFDPtr ; 
volatile U32 gCRxFDPtr, gPreviousFdp=0 ; 
volatile U32 gCam0_Addr0 = 0 , gCam0_Addr1 = 0  ; 
volatile U8 MyMacSrcAddr[6] ; 
volatile int WatchDogTime = 0 ; 
volatile int gErrorPacketCnt =0 ; 
volatile int BdmaRxDoneFlagForLoopBackCheck = 0 ; 
volatile int MacTxDoneFlagForLoopBackCheck = 0 ; 
 
// Global variable structure for store status 
pMACTxStatus gsMacTxStatus = {0,0,0,0,0,0,0,0,0,0,0} ; 
pMACRxStatus gsMacRxStatus = {0,0,0,0,0,0,0,0,0} ; 
pBDMATxStatus gsBdmaTxStatus = {0,0,0} ; 
pBDMARxStatus gsBdmaRxStatus = {0,0,0,0,0} ; 
 
 
 
 
//网络初始化 
void LanInitialize(void) 
{ 
  //配置物理收发设备 
	ResetPhyChip() ; 
 
  //获取MAC层网卡硬件物理地址 
	GetMyMacAddr() ; 
 
	// Initialize MAC and BDMA controller 
	MacInitialize() ; 
} 
 
/* 
 * void MacInitialize(void) 
 * Initialize MAC and BDMA Controller 
 */ 
void MacInitialize(void) 
{ 
 
	/*-----------------------------------------------------------------* 
	 * 1. Disable MAC and BDMA interrupts.                             * 
	 *-----------------------------------------------------------------*/ 
	Disable_Int(nMAC_RX_INT) ;     // Disable MAC Rx Interrupt 
	Disable_Int(nMAC_TX_INT) ;     // Disable MAC Tx Interrupt 
	Disable_Int(nBDMA_RX_INT) ;    // Disable BDMA Rx Interrupt 
	Disable_Int(nBDMA_TX_INT) ;    // Disable BDMA Tx Interrupt 
 
	/*-----------------------------------------------------------------* 
	 * 2. BDMA and MAC interrupt vector setup.                         *  
	 *-----------------------------------------------------------------*/ 
	SysSetInterrupt(nMAC_RX_INT, MAC_Rx_isr) ; 
	SysSetInterrupt(nMAC_TX_INT, MAC_Tx_isr) ; 
	SysSetInterrupt(nBDMA_RX_INT, BDMA_Rx_isr) ;  
	SysSetInterrupt(nBDMA_TX_INT, BDMA_Tx_isr) ; 
 
 
	/*-----------------------------------------------------------------* 
 	 * 3. Set the initial condition of the BDMA, and MAC               *  
 	 *-----------------------------------------------------------------*/ 
	BDMARXCON = BRxRS ;             // Reset BDMAC Receiver 
	BDMATXCON = BTxRS ;             // Reset BDMAC Transceiver 
	MACCON = SwReset ; 
	BDMARXLSZ = MaxRxFrameSize+40 ;    // 1520 
	MACCON = gMacCon ; 
 
	/*-----------------------------------------------------------------* 
 	 * 4. Set the BDMA Tx/Rx Frame Descriptor                          * 
 	 *-----------------------------------------------------------------*/ 
	TxFDInitialize() ; 
	RxFDInitialize() ; 
 
	/*-----------------------------------------------------------------* 
 	 * 5. Set the CAM Control register and the MAC address value       * 
 	 *-----------------------------------------------------------------*/ 
 	// CAM0 register of CAM registers : 0x9100~0x9103, 0x9104, 0x9105 
        CAM_Reg(0) =  gCam0_Addr0; 
        CAM_Reg(1) =  gCam0_Addr1; 
 
	// CAM Enable Register(CAMEN) 
	CAMEN = 0x0001 ; 
	CAMCON = gCamCon ; 
 
	/*-----------------------------------------------------------------* 
	 * 6. Enable interrupt BDMA Rx and MAC Tx interrupt.               * 
	 *-----------------------------------------------------------------*/ 
	Enable_Int(nBDMA_RX_INT);  
	Enable_Int(nMAC_TX_INT); 
	//Enable_Int(nMAC_RX_INT); 
 
	/*-----------------------------------------------------------------* 
 	 * 7. Configure the BDMA and MAC control registers.                * 
 	 *-----------------------------------------------------------------*/ 
	ReadyMacTx() ; 
	ReadyMacRx() ; 
} 
 
 
 
/* 
 * void TxFDInitialize(void) ; 
 *           Initialize Tx frame descriptor area-buffers. 
 */ 
void TxFDInitialize(void) 
{ 
	sFrameDescriptor *pFrameDescriptor; 
	sFrameDescriptor *pStartFrameDescriptor; 
	sFrameDescriptor *pLastFrameDescriptor = NULL; 
	U32 FrameDataAddr; 
	U32 i; 
 
	// Get Frame descriptor's base address.    
	// +0x4000000 is for setting this area to non-cacheable area.  
	BDMATXPTR = (U32)TxFDBaseAddr + 0x4000000; 
	gWTxFDPtr = gCTxFDPtr = BDMATXPTR; 
 
	// Get Transmit buffer base address. 
	FrameDataAddr = (U32)TxFBABaseAddr + 0x4000000; 
 
	// Generate linked list. 
	pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr; 
	pStartFrameDescriptor = pFrameDescriptor; 
 
	for(i=0; i < MaxTxFrameDescriptors; i++)  { 
		if(pLastFrameDescriptor == NULL) 
			pLastFrameDescriptor = pFrameDescriptor; 
		else  	pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor; 
 
		pFrameDescriptor->FrameDataPtr =  
			(U32)(FrameDataAddr & fOwnership_CPU); 
		pFrameDescriptor->Reserved = (U32)0x0; 
		pFrameDescriptor->StatusAndFrameLength = (U32)0x0; 
		pFrameDescriptor->NextFrameDescriptor = NULL; 
 
		pLastFrameDescriptor = pFrameDescriptor; 
		pFrameDescriptor++; 
		FrameDataAddr += sizeof(sMACFrame); 
	} // end for loop 
 
	// Make Frame descriptor to ring buffer type.      
	pFrameDescriptor--;  
	pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor; 
} 
 
/* 
 * void RxFDInitialize(void) ; 
 *           Initialize Rx frame descriptor area-buffers. 
 */ 
void RxFDInitialize(void) 
{ 
	sFrameDescriptor *pFrameDescriptor; 
	sFrameDescriptor *pStartFrameDescriptor; 
	sFrameDescriptor *pLastFrameDescriptor = NULL; 
	U32 FrameDataAddr; 
	U32 i; 
 
	// Get Frame descriptor's base address.   
	// +0x4000000 is for setting this area to non-cacheable area.  
	BDMARXPTR = (U32)RxFDBaseAddr + 0x4000000; 
	gCRxFDPtr = BDMARXPTR; 
	 
	// Get Transmit buffer base address.   
	FrameDataAddr = (U32)RxFBABaseAddr + 0x4000000; 
 
	// Generate linked list.  
	pFrameDescriptor = (sFrameDescriptor *) gCRxFDPtr; 
	pStartFrameDescriptor = pFrameDescriptor; 
	 
	for(i=0; i < MaxRxFrameDescriptors; i++)  { 
		if(pLastFrameDescriptor == NULL) 
			pLastFrameDescriptor = pFrameDescriptor; 
		else  	pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor; 
 
		pFrameDescriptor->FrameDataPtr = 
		(U32)(FrameDataAddr | fOwnership_BDMA | 0x4000000 ); 
		pFrameDescriptor->Reserved = (U32)0x0; 
		pFrameDescriptor->StatusAndFrameLength = (U32)0x0; 
		pFrameDescriptor->NextFrameDescriptor = NULL; 
		 
		pLastFrameDescriptor = pFrameDescriptor; 
		pFrameDescriptor++; 
		FrameDataAddr += sizeof(sMACFrame);  
	} // end for loop 
       
	// Make Frame descriptor to ring buffer type.      
	pFrameDescriptor--;  
	pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor; 
} 
 
 
 
/* 
 * Function : ReadyMacTx 
 * Description : set Tx Registers related with BDMA & MAC to transmit 
 *               packet. 
 */ 
void ReadyMacTx(void) 
{ 
	BDMATXCON = gBdmaTxCon ; 
	MACTXCON =  gMacTxCon ; 
} 
 
/* 
 * Function : ReadyMacRx 
 * Description : set Rx Registers related with BDMA & MAC to Receive packet. 
 */ 
void ReadyMacRx(void) 
{ 
	BDMARXCON = gBdmaRxCon ; 
	MACRXCON = gMacRxCon ; 
} 
 
/* 
 * Function : MacTxGo 
 * Description : MAC Transfer Start for interactive mode 
 */ 
void MacTxGo(void) 
{ 
	// Enable MAC and BDMA Transfer 
	if (!(BDMATXCON & BTxEn))  BDMATXCON |= BTxEn ; 
	MACTXCON |= TxEn  ; 
} 
 
 
 
/* 
 * Function : GetMyMacAddr  
 * Description : Get MAC Address From IIC EEPROM 
 */ 
	 
void GetMyMacAddr(void) 
{ 
	U8 MacAddr[MAC_ADDR_SIZE]; 
	U8 TempAddr[MAC_ADDR_SIZE]; 
	int i; 
	 
	gCam0_Addr0 = gCam0_Addr1 = 0 ; 
 
	MacAddr[0] = 0x55 ; 
	MacAddr[1] = 0x44 ; 
	MacAddr[2] = 0x33 ; 
	MacAddr[3] = 0x22 ; 
	MacAddr[4] = 0x11 ; 
	MacAddr[5] = 0x00 ; 
 
	/* Get MAC Address */ 
	for (i=0;i<(int)MAC_ADDR_SIZE;i++)  TempAddr[i] = MacAddr[i]; 
	 
	/* Copy MAC Address to global variable */ 
	for (i=0;i<(int)MAC_ADDR_SIZE-2;i++) 
		gCam0_Addr0 = (gCam0_Addr0 << 8) | TempAddr[i] ; 
 
	for (i=(int)(MAC_ADDR_SIZE-2);i<(int)MAC_ADDR_SIZE;i++) 
		gCam0_Addr1 = (gCam0_Addr1 << 8) | TempAddr[i] ; 
	gCam0_Addr1 = (gCam0_Addr1 << 16) ; 
 
 	/* Set CAM0 register : 0x9100~0x9103, 0x9104, 0x9105 */ 
        CAM_Reg(0) =  gCam0_Addr0; 
        CAM_Reg(1) =  gCam0_Addr1; 
 
	for (i=0;i<(int)MAC_ADDR_SIZE;i++) MyMacSrcAddr[i] = TempAddr[i]; 
} 
 
 
/* 
 * Function : ResetPhyChip 
 * Description : Reset The Phychip, Auto-Negotiation Enable  
 */ 
void ResetPhyChip(void) 
{ 
  //10Mbps 半双工模式 
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,0x0);  
  //10Mbps 全双工模式  
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,PHY_FULLDUPLEX);  
  //100Mbps 半双工模式  
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB); 
  //100Mbps 全双工模式  
  //MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,DR_100MB|PHY_FULLDUPLEX);  
  //自动检测配置 
    MiiStationWrite(PHY_CNTL_REG,PHYHWADDR,ENABLE_AN|RESTART_AN); 
} 
 
/* 
 * Function : MiiStationRead, MiiStationWrite   
 * Description : MII Interface Station Management Register Read or Write 
 * Input : PhyInAddr(PHY internal register address) 
 *         PhyAddr(PHY unique address) 
 *         PhyWrData(When Write)  
 * Output: PhyRdData(WhenRead)  
 */ 
void MiiStationWrite(U32 PhyInAddr, U32 PhyAddr, U32 PhyWrData) 
{ 
	STADATA = PhyWrData ; 
	STACON = PhyInAddr | PhyAddr |  MiiBusy | PHYREGWRITE ; 
	while( (STACON & MiiBusy) )  ; 
	delay_physet() ; 
} 
U32 MiiStationRead(U32 PhyInAddr, U32 PhyAddr)  
{ 
	U32	PhyRdData ; 
	STACON = PhyInAddr | PhyAddr |  MiiBusy ; 
	while( (STACON & MiiBusy) )  ; 
	PhyRdData = STADATA ; 
	return PhyRdData ; 
} 
 
void delay_physet(void)  
{ 
	int i=1000 ; 
	while(i--) ; 
} 
 
 
/* 
 * Function : MAC_Tx_isr 
 * Description : Interrupt Service Routine for MAC Tx 
 */ 
void MAC_Tx_isr(void) 
{    
 
	sFrameDescriptor *pTxFDptr; 
	U32 *pFrameDataPtr ; 
	U32 Status ; 
	U32 CTxPtr ; 
	 
 
	CTxPtr = BDMATXPTR ; 
 
	while ( gCTxFDPtr != CTxPtr )  {  
		pTxFDptr = (sFrameDescriptor *) gCTxFDPtr; 
 
		// Check CPU ownership 
		// if Owner is BDMA then break 
		pFrameDataPtr = (U32 *)&pTxFDptr->FrameDataPtr; 
		if ( (*pFrameDataPtr & fOwnership_BDMA) ) break ; 
	 
		Status = (pTxFDptr->StatusAndFrameLength >> 16) & 0xffff; 
	 
		if (Status & Comp) { 
			gsMacTxStatus.MacTxGood++ ; 
		} 
		else 
		{ 
			// Save Error status 
			// Check each status, because, error can duplicated 
			if (Status & Under) gsMacTxStatus.UnderErr++ ; 
			if (Status & ExColl) gsMacTxStatus.ExCollErr++ ; 
			if (Status & TxDeffer) gsMacTxStatus.TxDefferedErr++ ; 
			if (Status & Paused) gsMacTxStatus.sPaused++ ; 
			if (Status & Defer) gsMacTxStatus.DeferErr++ ; 
			if (Status & NCarr) gsMacTxStatus.NCarrErr++ ; 
			if (Status & SQErr) gsMacTxStatus.sSQE++ ; 
			if (Status & LateColl) gsMacTxStatus.LateCollErr++ ; 
			if (Status & TxPar) gsMacTxStatus.TxParErr++ ; 
			if (Status & TxHalted) gsMacTxStatus.sTxHalted++ ; 
    		 
			// Set MAC/BDMA Tx control register for next use. 
 
			ReadyMacTx() ; 
		} // end if 
 
		// Clear Framedata pointer already used. 
		pTxFDptr->StatusAndFrameLength = (U32)0x0; 
 
		gCTxFDPtr = (U32)pTxFDptr->NextFrameDescriptor ; 
	} // end while loop 
 
 
} 
 
/* 
 * Function : MAC_Rx_isr 
 * Description : Interrupt Service Routine for MAC Rx 
 * Not Used 
 */ 
void MAC_Rx_isr(void) { } 
 
 
/* 
 * Function : BDMA_Tx_isr 
 * Description : Interrupt Service Routine for BDMA Tx 
 * Not Used 
 */ 
void BDMA_Tx_isr(void) { } 
 
/* 
 * Function : BDMA_Rx_isr 
 * Description : Interrupt Service Routine for BDMA Rx 
 * Ethenet Frame is received in BDMA_Rx_isr 
 */ 
 
 
void BDMA_Rx_isr(void) 
{ 
	sFrameDescriptor *pRxFDptr ; 
	U32 RxStatus, FrameLength ; 
	U32 CRxPtr; 
	U32 sBdmaStat ; 
	U8 *pFrameData ; 
	// Step 1. Get current frame descriptor and status 
	CRxPtr = BDMARXPTR ; 
	sBdmaStat = BDMASTAT ; 
 
	// Step 2. Clear BDMA status register bit by write 1 
	BDMASTAT |= S_BRxRDF ; 
	gsBdmaRxStatus.BdmaRxCnt++ ; 
 
 
 
	do { 
		// Step 3. Check Null List Interrupt 
		if ( BDMASTAT & S_BRxNL ) { 
			BDMASTAT |= S_BRxNL ; 
			gsBdmaRxStatus.BRxNLErr++ ; 
			MacInitialize() ; 
			break ; 
		} 
 
		// Step 4. Get Rx Frame Descriptor 
		pRxFDptr = (sFrameDescriptor *)gCRxFDPtr ; 
		RxStatus = (pRxFDptr->StatusAndFrameLength >> 16) & 0xffff; 
 
		// Step 5. If Rx frame is good, then process received frame 
		if((RxStatus & RxGood)&&!(RxStatus & OvMax)) { 
			FrameLength = pRxFDptr->StatusAndFrameLength & 0xffff ;  
			pFrameData = (U8 *)pRxFDptr->FrameDataPtr ; 
			gsBdmaRxStatus.BdmaRxGood++ ; 
			// Step 6. Get received frame to memory buffer 
			 
			 
			//由丁一修改 
			ethernetif_input(netif_default,pFrameData ,FrameLength); 
 
			 
		} else { 
			//put_byte('q'); 
			// Step 7. If Rx frame has error, then process error frame 
			gErrorPacketCnt++ ; 
 
			// Save Error status 
			// Check each status, because, error can duplicated 
			if (RxStatus & OvMax) gsMacRxStatus.OvMaxSize++ ; 
			if (RxStatus & CtlRecd) gsMacRxStatus.sCtlRecd++ ; 
			if (RxStatus & Rx10Stat) gsMacRxStatus.sRx10Stat++ ; 
			if (RxStatus & AlignErr) gsMacRxStatus.AllgnErr++ ; 
			if (RxStatus & CRCErr) gsMacRxStatus.sCRCErr++ ; 
			if (RxStatus & Overflow) gsMacRxStatus.OverflowErr++ ; 
			if (RxStatus & LongErr)	 gsMacRxStatus.sLongErr++ ; 
			if (RxStatus & RxPar) gsMacRxStatus.RxParErr++ ; 
			if (RxStatus & RxHalted) gsMacRxStatus.sRxHalted++ ; 
		} 
 
		// Step 8. Change ownership to BDMA for next use 
		(pRxFDptr->FrameDataPtr) |= fOwnership_BDMA; 
 
		// Save Current Status and Frame Length field, and clear 
		pRxFDptr->StatusAndFrameLength = (U32)0x0; 
 
		// Step 9. Get Next Frame Descriptor pointer to process 
		gCRxFDPtr = (U32)(pRxFDptr->NextFrameDescriptor) ; 
 
	} while (CRxPtr != gCRxFDPtr); 
 
	// Step 10. Check Notowner status 
	if ( sBdmaStat & S_BRxNO ) { 
		BDMASTAT |= S_BRxNO ; 
		gsBdmaRxStatus.BRxNOErr++ ; 
		ReadyMacRx() ; 
	} 
 
} 
 
 
/* 
 * Function : SendPacket 
 * Description : Send ethernet frame function 
 * Input : frame data pointer, frame length 
 * Output : transmit ok(1) or error(0) 
 */ 
int SendPacket( unsigned char* Data,int Size) 
{ 
	sFrameDescriptor	*psTxFD; 
	U32			*pFrameDataPtr ; 
	U8 			*pFrameData ; 
	int			FrameLength ; 
 
 
	// 1. Get Tx frame descriptor & data pointer 
	psTxFD = (sFrameDescriptor *)gWTxFDPtr ; 
 
	pFrameData = (U8 *)psTxFD->FrameDataPtr ; 
	pFrameDataPtr = (U32 *)&psTxFD->FrameDataPtr; 
	FrameLength = Size + sizeof(etheader) ; 
 
	// 2. Check BDMA ownership 
	if ( (*pFrameDataPtr & fOwnership_BDMA) ) return 0 ; 
 
	// 3. Prepare Tx Frame data to Frame buffer 
	memcpy ((U8 *)pFrameData,(U8 *)Data,FrameLength); 
 
	// 4. Set TX Frame flag & Length Field 
 
	psTxFD->Reserved = (PaddingMode | CRCMode | SourceAddrIncrement | \ 
			LittleEndian | WidgetAlign00 | MACTxIntEn); 
 
	psTxFD->StatusAndFrameLength = (U32)(FrameLength & 0xffff); 
 
	// 5. Cheange ownership to BDMA 
	psTxFD->FrameDataPtr |= fOwnership_BDMA; 
 
	// 6. Enable MAC and BDMA Tx control register 
	MacTxGo(); 
 
	// 7. Change the Tx frame descriptor for next use 
	gWTxFDPtr = (U32)(psTxFD->NextFrameDescriptor); 
 
	return 1 ; 
}