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

📄 packetdriver.c

📁 一个ARM7 芯片Bootload中几个重要的实用代码。比如DHCP
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 *
 * Copyright (c) 2003 Windond Electronics Corp.
 * All rights reserved.
 * Winbond W90N740 Boot Loader
 *
 * Module Name:	PACKETDRIVER.C
 *
 * Created by : 
 ******************************************************************************/
#include "netbuf.h"
#include "w90n740.h"
#include "net.h"

//#define USE_RMII
//#define PHY
//#define MARVELL_6052
//#define IC_PLUS 
INT _phy=NET_IC_PLUS;
INT _rmii=0;

volatile INT MAC_NUM = 0;

__align(16) static sFrameDescriptor RxFDBaseAddr0[MaxRxFrameDescriptors];
__align(16) static sFrameDescriptor RxFDBaseAddr1[MaxRxFrameDescriptors];
__align(16) static sFrameDescriptor TxFDBaseAddr0[MaxTxFrameDescriptors];
__align(16) static sFrameDescriptor TxFDBaseAddr1[MaxTxFrameDescriptors];


// Global variables  used for MAC driver
#ifdef USE_RMII
volatile UINT32 gMCMDR = MCMDR_FDUP | MCMDR_SPCRC | MCMDR_RXON | 
                           MCMDR_EnMDC | MCMDR_AEP | MCMDR_ACP | MCMDR_EnRMII;
#else
volatile UINT32 gMCMDR = MCMDR_FDUP | MCMDR_SPCRC | MCMDR_RXON | 
                           MCMDR_EnMDC | MCMDR_AEP | MCMDR_ACP;
#endif
                      
volatile UINT32 gMIEN = EnTXINTR | EnTXCP | EnRXINTR | EnTDU | EnRXGD | 
                          EnCRCE | EnRP | EnPTLE | EnRXOV |
                          EnLC | EnTXABT | EnNCS | EnEXDEF | EnTXEMP |
                          EnTxBErr | EnRxBErr | EnRDU | EnCFR;
                     
volatile UINT32 gCAMCMR = CAM_ECMP;

volatile UINT32 gCTxFDPtr[2], gWTxFDPtr[2], gCRxFDPtr[2];
volatile UINT32 gCam0M_0 = 0 , gCam0L_0 = 0;
volatile UINT32 gCam0M_1 = 0 , gCam0L_1 = 0;
volatile INT TDU_Flag0, TDU_Flag1;

volatile char TxReady0=1, TxReady1=1;

NETBUF	*_TxQueue0 = NULL, *_TxQueue1 = NULL;

// Interrupt Handler Table
typedef void (*fptr)();  // function pointer
fptr IRQ_HandlerTable[19];

extern void MAC0_Tx_isr(void) ;
extern void MAC0_Rx_isr(void) ;
extern void MAC1_Tx_isr(void) ;
extern void MAC1_Rx_isr(void) ;

extern UCHAR  _HostMAC[];
extern UCHAR  _HostIP[];


void  GetMacAddress(char *mac)
{
	memcpy((char *)mac, (char *)_HostMAC, 6);
}

void  SetMacAddress(char *mac)
{
	memcpy((char *)_HostMAC, (char *)mac, 6);
}

void SetIpAddress(char *ip)
{
	memcpy((char *)_HostIP, (char *)ip, 4);
}

void GetIpAddress(char *ip)
{
	memcpy((char *)ip, (char *)_HostIP, 4);
}

void SetMacNumber(INT num)
{
 	if ((num==0)||(num==1))	
   		MAC_NUM = num;	
}	

void SetPhyChip(INT num)
{
	_phy=num;
}

void SetRMII(INT num)
{
	if( num == 1)
		_rmii = 1;
	else
		_rmii = 0;
		
}

// Setup Interrupt Handler Vector Table
void SysSetInterrupt(volatile UINT32 vector, void (*handler)())
{
 	IRQ_HandlerTable[vector] = handler;
}



// Interrupt Service Routine                                                                         */
__irq void IRQ_IntHandler(void)
{
// 	UINT32 IPER, ISNR;
	UINT32 irq;

// 	IPER = AIC_IPER >> 2;
// 	ISNR = AIC_ISNR;
	irq=AIC_ISR;
	if( irq & (0x1<<13) )
		(*IRQ_HandlerTable[13])();
	if( irq & (0x1<<14) )
		(*IRQ_HandlerTable[14])();
	if( irq & (0x1<<15) )
		(*IRQ_HandlerTable[15])();
	if( irq & (0x1<<16) )
		(*IRQ_HandlerTable[16])();

// 	if (ISNR == IPER)
// 		if((IPER >=13) && (IPER <=16) )
//   			(*IRQ_HandlerTable[ISNR])();

// 	AIC_EOSCR = 0;
}



void Mac_EnableInt()
{
 	if (MAC_NUM == 0)
   	{
    	Enable_Int(EMCTXINT0);
    	Enable_Int(EMCRXINT0);
   	}
 	else if (MAC_NUM == 1)
   	{
    	Enable_Int(EMCTXINT1);
    	Enable_Int(EMCRXINT1);
   	}
}



void Mac_DisableInt()
{
 	if (MAC_NUM == 0)
   	{
   		Disable_Int(EMCTXINT0);
    	Disable_Int(EMCRXINT0);
   	}
 	else if (MAC_NUM == 1)
   	{
    	Disable_Int(EMCTXINT1);
    	Disable_Int(EMCRXINT1);
   	}
}



void Mac_EnableBroadcast()
{
 	if (MAC_NUM == 0)
   		CAMCMR_0 |= CAM_ABP ;
 	else 
 	if (MAC_NUM == 1)
   		CAMCMR_1 |= CAM_ABP ;
}



void Mac_DisableBroadcast()
{
 	if (MAC_NUM == 0)
   		CAMCMR_0 &= ~CAM_ABP ;
 	else 
 	if (MAC_NUM == 1)
   		CAMCMR_1 &= ~CAM_ABP ;
}



// MII Interface Station Management Register Write
void MiiStationWrite(INT num, UINT32 PhyInAddr, UINT32 PhyAddr, UINT32 PhyWrData)
{
 	volatile INT i = 1000;

/*	
#ifdef MARVELL_6052
	num = 0;
#endif

#ifdef IC_PLUS
	num = 0;
#endif		
*/
//if( _phy != NET_PHY )num=0; //CWS 5/20

	
 	if (num == 0)
   	{
    	MIID_0 = PhyWrData ;
    	MIIDA_0 = PhyInAddr | PhyAddr | PHYBUSY | PHYWR | MDCCR;
    	
    	while (i--) ;
    	while ( (MIIDA_0 & PHYBUSY) )  ;
   	}
 	else 
 	if (num == 1)
   	{
    	MIID_1 = PhyWrData ;
    	MIIDA_1 = PhyInAddr | PhyAddr | PHYBUSY | PHYWR | MDCCR;
    	
    	while (i--) ;
    	while ( (MIIDA_1 & PHYBUSY) )  ;
    }
   
}



// MII Interface Station Management Register Read
UINT32 MiiStationRead(INT num, UINT32 PhyInAddr, UINT32 PhyAddr)
{
 	UINT32 PhyRdData ;
/* 	
#ifdef  MARVELL_6052
	num = 0;
#endif

#ifdef  IC_PLUS
	num = 0;
#endif			
*/
//	if( _phy!=NET_PHY )num=0; //CWS 5/20

 	if (num == 0)
   	{
    	MIIDA_0 = PhyInAddr | PhyAddr | PHYBUSY | MDCCR;
    	while( (MIIDA_0 & PHYBUSY) )  ;
    	PhyRdData = MIID_0 ;  
   	}
 	else if (num == 1)
   	{
    	MIIDA_1 = PhyInAddr | PhyAddr | PHYBUSY | MDCCR;
    	while( (MIIDA_1 & PHYBUSY) )  ;
    	PhyRdData = MIID_1 ;
    }

 	return PhyRdData ;
}



// Reset PHY, Auto-Negotiation Enable
void ResetPhyChip(INT num)
{

  	UINT32	RdValue;
  	INT		t0;
  	UINT32 i;

//#ifdef MARVELL_6052
switch(_phy)
{
case NET_MARVELL6052:	

  	if (num == 0) 
  	{
    	uprintf("setting lan side vlan table\r\n");
    	for (i = 8; i < 0xf; i ++) 
    	{
     		RdValue = MiiStationRead(0, 0x04, (0x1000 |(i << 8)) );
      		MiiStationWrite(0, 0x04, (0x1000 | (i << 8)), RdValue | 0x3);  // enable all ports
    	}

    	MiiStationWrite(0, 0x00, 0x1100, ENABLE_AN | RESTART_AN);
    	MiiStationWrite(0, 0x00, 0x1200, ENABLE_AN | RESTART_AN);
    	MiiStationWrite(0, 0x00, 0x1300, ENABLE_AN | RESTART_AN);
    	MiiStationWrite(0, 0x00, 0x1400, ENABLE_AN | RESTART_AN);
    
    	MiiStationWrite(0, 0x06, 0x1900, 0x003c);   // port 1 for LAN 
    	MiiStationWrite(0, 0x06, 0x1a00, 0x003a);	// port 2 
    	MiiStationWrite(0, 0x06, 0x1b00, 0x0036);   // port 3 
    	MiiStationWrite(0, 0x06, 0x1c00, 0x002e);   // port 4 
    	MiiStationWrite(0, 0x06, 0x1d00, 0x001e);   // port 5 connect to CPU MAC 0 
    
    	/* set MAC 0 to 100 full */
    	MCMDR_0 |= MCMDR_OPMOD;
    	MCMDR_0 |= MCMDR_FDUP;
  	} 
  	else 
  	{
      	uprintf("setting wan side vlan table\r\n");

    	for (i = 8; i < 0xf; i ++) 
    	{
      		RdValue = MiiStationRead(0, 0x04, (0x1000 |(i << 8)) );
      		MiiStationWrite(0, 0x04, (0x1000 | (i << 8)), RdValue | 0x3);  // enable all ports
    	}
    	MiiStationWrite(0, 0x00, 0x1000, ENABLE_AN | RESTART_AN);
    	MiiStationWrite(0, 0x06, 0x1800, 0x1040);	// port 0 for WAN 
    	MiiStationWrite(0, 0x06, 0x1e00, 0x1001);	// port 6 connect to CPU port 1 
   
    	/* set MAC 1 to 100 full */
    	MCMDR_1 |= MCMDR_OPMOD;
    	MCMDR_1 |= MCMDR_FDUP;
  	}
  	return;
//#endif

case NET_IC_PLUS:
//#ifdef IC_PLUS

#define IEEE_802_3_CSMA_CD   1

  	t0 = 1000000;
  	if (1)
  	{	    
  		if( num == 0 ) // CWS 6/10
  		{
	    	MiiStationWrite(0, 0x16, PHYAD, 0x8420);
    		RdValue = MiiStationRead(0, 0x12, PHYAD);	  
    		MiiStationWrite(0, 0x12, PHYAD, RdValue | 0x80); // enable MII registers
    	}

    	if (num == 1) 
    	{
      		MiiStationWrite(num, PHY_ANA_REG, PHYAD, DR100_TX_FULL|DR100_TX_HALF|\
		      				DR10_TX_FULL|DR10_TX_HALF|IEEE_802_3_CSMA_CD);      //CWS 6/10
      		MiiStationWrite(num, PHY_CNTL_REG, PHYAD, ENABLE_AN | RESET_PHY|RESTART_AN);
      
      		uprintf("Wait for auto-negotiation complete...");
      		
      		while (1) 	/* wait for auto-negotiation complete */
      		{
				RdValue = MiiStationRead(num, PHY_STATUS_REG, PHYAD) ;
				if ((RdValue & AN_COMPLETE) != 0)
				{
	  				uprintf("OK\n");
	  				break;
				}
				//if (NU_Retrieve_Clock() - t0 > 3 * NU_PLUS_Ticks_Per_Second) 
				if ( !(t0--) )
				{
	  				uprintf("FAILED!!\n");
	  				/* By default, we set the MAC to work under 100M/Full-duplex */

	  				MCMDR_1 |= MCMDR_OPMOD;
	  				MCMDR_1 |= MCMDR_FDUP;				
	  				return;
				}
      		}	/* end of while */
    	}
  	}

  	if (num == 1) 
  	{
	  	/* read the result of auto-negotiation */
    	RdValue = MiiStationRead(num, PHY_CNTL_REG, PHYAD) ;
    	if (RdValue & DR_100MB) 
    	{						
      		uprintf("100MB - ");
      		MCMDR_1 |= MCMDR_OPMOD;
      
    	} 
    	else 
    	{
      		uprintf("10MB - ");
      		MCMDR_1 &= ~MCMDR_OPMOD;
    	}
    	
    	if (RdValue & PHY_FULLDUPLEX) 
    	{
      		uprintf("Full Duplex\n");
      		MCMDR_1 |= MCMDR_FDUP;
    	} 
    	else 
    	{
      		uprintf("Half Duplex\n");
      		MCMDR_1 &= ~MCMDR_FDUP;
    	}	 
    	
    	/* Fix IC PLUS 10half collision bug */
    	RdValue = MiiStationRead(num, 0x1d, PHYAD); 
    	RdValue |= 0x0100;
    	MiiStationWrite(num, 0x1d, PHYAD, RdValue);
  	} 
  	else 
  	{
    	/* MAC0 fixed to 100/Full */
    	MCMDR_0 |= MCMDR_OPMOD;
    	MCMDR_0 |= MCMDR_FDUP;
  	}
  	return;

//#endif
default:
case NET_PHY:
//#ifdef PHY
  	t0 = 1000000;
  	if (1)
  	{	    
    	MiiStationWrite(num, PHY_CNTL_REG, PHYAD, ENABLE_AN | RESTART_AN);
    	uprintf("Wait for auto-negotiation complete...");
		
    	while (1) 	/* wait for auto-negotiation complete */
    	{
      		RdValue = MiiStationRead(num, PHY_STATUS_REG, PHYAD) ;
      
      		if ((RdValue & AN_COMPLETE) != 0)
      		{
				uprintf("OK\n");
				break;
      		}

      		if (!(t0--)) 
      		{
				uprintf("FAILED!!\n");
				
				/* By default, we set the MAC to work under 100M/Full-duplex */
				if (num == 0)
				{
	  				MCMDR_0 |= MCMDR_OPMOD;
	  				MCMDR_0 |= MCMDR_FDUP;				
				}
				else
				{
	  				MCMDR_1 |= MCMDR_OPMOD;
	  				MCMDR_1 |= MCMDR_FDUP;				
				}
				return;
      		}
    	}
  	}
	
  	/* read the result of auto-negotiation */
  	RdValue = MiiStationRead(num, PHY_CNTL_REG, PHYAD) ;
  	if (RdValue & DR_100MB)			/* 100MB */
  	{
    	uprintf("100MB - ");
    	if (num == 1)
      		MCMDR_1 |= MCMDR_OPMOD;
    	else
      		MCMDR_0 |= MCMDR_OPMOD;
  	}
  	else 
  	{
    	uprintf("10MB - ");
    	if (num == 1)
      		MCMDR_1 &= ~MCMDR_OPMOD;
    	else
      		MCMDR_0 &= ~MCMDR_OPMOD;
  	}
  
  	if (RdValue & PHY_FULLDUPLEX) 	/* Full Duplex */
  	{
    	uprintf("Full Duplex\n");
    	if (num == 1)
      		MCMDR_1 |= MCMDR_FDUP;
    	else
      		MCMDR_0 |= MCMDR_FDUP;
  	}
  	else 
  	{	 
    	uprintf("Half Duplex\n");
    	if (num == 1)
      		MCMDR_1 &= ~MCMDR_FDUP;
    	else
      		MCMDR_0 &= ~MCMDR_FDUP;
  	}	 
  	return;

//#endif
}
}



void EnableCamEntry(INT num, INT entry)
{
 	if (num == 0)
   		CAMEN_0 |= 0x00000001 << entry ;
 	else 
 	if (num == 1)
   		CAMEN_1 |= 0x00000001 << entry ;
}



void DisableCamEntry(INT num, INT entry)
{
 	if (num == 0)
   		CAMEN_0 &= ~(0x00000001 << entry) ;
 	else 
 	if (num == 1)
   		CAMEN_1 &= ~(0x00000001 << entry) ;
}



void FillCamEntry(INT num, INT entry, UINT32 msw, UINT32 lsw)
{
 	if (num==0)
   	{
    	CAMxM_Reg_0(entry) = msw;
    	CAMxL_Reg_0(entry) = lsw;
   	}
 	else if (num==1)
   	{
    	CAMxM_Reg_1(entry) = msw;
    	CAMxL_Reg_1(entry) = lsw;
   	}
 	EnableCamEntry(num,entry);
}



// Set MAC Address to CAM
void SetMacAddr(INT num)
{
 	INT i;
 	UCHAR  mac[6];

 	GetMacAddress((CHAR *)mac);
 	if (num == 0)
   	{
    	/* Copy MAC Address to global variable */
    	for (i = 0; i < (INT)MAC_ADDR_SIZE-2; i++)
       		gCam0M_0 = (gCam0M_0 << 8) | mac[i] ;

    	for (i = (INT)(MAC_ADDR_SIZE-2); i < (INT)MAC_ADDR_SIZE; i++)
       		gCam0L_0 = (gCam0L_0 << 8) | mac[i] ;
    
    	gCam0L_0 = (gCam0L_0 << 16) ;

    	FillCamEntry(0, 0, gCam0M_0, gCam0L_0);
   	}
 	else 
 	if (num == 1)
   	{
    	/* Copy MAC Address to global variable */
    	for (i = 0; i < (INT)MAC_ADDR_SIZE-2; i++)
       		gCam0M_1 = (gCam0M_1 << 8) | mac[i] ;

    	for (i = (INT)(MAC_ADDR_SIZE-2); i < (INT)MAC_ADDR_SIZE; i++)
       		gCam0L_1 = (gCam0L_1 << 8) | mac[i] ;
    	
    	gCam0L_1 = (gCam0L_1 << 16) ;

    	FillCamEntry(1, 0, gCam0M_1, gCam0L_1);
   	}
}



// Initialize Tx frame descriptor area-buffers.
void TxFDInitialize(INT num)
{
 	sFrameDescriptor 	*pFrameDescriptor;
 	sFrameDescriptor 	*pStartFrameDescriptor;
 	sFrameDescriptor 	*pLastFrameDescriptor = NULL;
 	UINT32 			i;

 	if (num == 0)
   	{
    	// Get Frame descriptor's base address.
    	TXDLSA_0 = (UINT32)TxFDBaseAddr0 | 0x80000000;
    	gWTxFDPtr[0] = gCTxFDPtr[0] = TXDLSA_0;

    	// Generate linked list.
    	pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[0];
    	pStartFrameDescriptor = pFrameDescriptor;

    	for(i = 0; i < MaxTxFrameDescriptors; i++)
    	{
     		if (pLastFrameDescriptor == NULL)
       			pLastFrameDescriptor = pFrameDescriptor;
     		else
       			pLastFrameDescriptor->NextFrameDescriptor = (UINT32)pFrameDescriptor;

     		pFrameDescriptor->Status1 = (PaddingMode | CRCMode | MACTxIntEn);
     		pFrameDescriptor->FrameDataPtr = (UINT32)0x0;
     		pFrameDescriptor->Status2 = (UINT32)0x0;
     		pFrameDescriptor->NextFrameDescriptor = NULL;

     		pLastFrameDescriptor = pFrameDescriptor;
     		pFrameDescriptor++;
    	}

    	// Make Frame descriptor to ring buffer type.
    	pFrameDescriptor--;
    	pFrameDescriptor->NextFrameDescriptor = (UINT32)pStartFrameDescriptor;
   	}
 	else 
 	if (num == 1)
   	{
    	// Get Frame descriptor's base address.
    	TXDLSA_1 = (UINT32)TxFDBaseAddr1 | 0x80000000;
    	gWTxFDPtr[1] = gCTxFDPtr[1] = TXDLSA_1;

    	// Generate linked list.
    	pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[1];
    	pStartFrameDescriptor = pFrameDescriptor;

    	for (i = 0; i < MaxTxFrameDescriptors; i++)
    	{
     		if (pLastFrameDescriptor == NULL)
       			pLastFrameDescriptor = pFrameDescriptor;
     		else
       			pLastFrameDescriptor->NextFrameDescriptor = (UINT32)pFrameDescriptor;

     		pFrameDescriptor->Status1 = (PaddingMode | CRCMode | MACTxIntEn);
     		pFrameDescriptor->FrameDataPtr = (UINT32)0x0;
     		pFrameDescriptor->Status2 = (UINT32)0x0;
     		pFrameDescriptor->NextFrameDescriptor = NULL;

⌨️ 快捷键说明

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