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

📄 mac_au1000.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					t_MAC_AU1000_device *pdevice,
					int reg
					)
{
	/* check link status, spin here till done */
	while ( MACREG( pdevice->pAU1000CtrlRegs, MAC_MIICTRL) 
					& MAC_MIICTRL_MBUSY_MASK) ;

	MACREG(pdevice->pAU1000CtrlRegs, MAC_MIICTRL) = (reg << 6);

	/* check link status, spin here till done */
	while ( MACREG( pdevice->pAU1000CtrlRegs, MAC_MIICTRL) 
					& MAC_MIICTRL_MBUSY_MASK) ;

	return MACREG(pdevice->pAU1000CtrlRegs, MAC_MIIDATA);
}
	
static
INT32 MAC_AU1000_MII_init( t_MAC_AU1000_device *pdevice )		   
{
	int   i ;
	INT32 rcode ;

#ifdef BE1000_CONFIG
        DISP_STR("MII INIT");
        MAC_MII_WRITE(pdevice,0,0x3200);	// reset Autonegotiation
        MAC_MII_WRITE(pdevice,17,0xffc0);	// set LEDs to display correctly
#endif

#ifdef BOSPORUS_CONFIG
        DISP_STR("SWITCH INIT");
        bosporus_init_switch();
#endif

#ifdef PB1500_CONFIG
        DISP_STR("MII INIT");
        MAC_MII_WRITE(pdevice,0,0x3200);	// reset Autonegotiation
        MAC_MII_WRITE(pdevice,17,0xffc0);	// set LEDs to display correctly
#endif

#ifdef PB1100_CONFIG
	DISP_STR("MII INIT");
	MAC_MII_WRITE(pdevice,0,0x3200);	// reset Autonegotiation
	MAC_MII_WRITE(pdevice,17,0xffc0);	// set LEDs to display correctly
#endif

	return(OK) ;
}


/************************************************************************
 *
 *                          MAC_AU1000_control_init
 *  Description :
 *  -------------
 *    This routine initialize the AU1000 Control Register
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  'pdevice',     IN,    reference for this device  context
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *
 *
 *
 ************************************************************************/
static
INT32 MAC_AU1000_control_init( t_MAC_AU1000_device *pdevice )		   
{
	
	INT32 rcode;
	int i;
	
	t_mac_addr mac_addr ;

	/* get MAC address from board */
	IF_ERROR( (rcode),
			  (SYSCON_read( SYSCON_COM_EN0_MAC_ADDR_ID,
							&(mac_addr),
							sizeof(mac_addr)) ) ) 

	for(i=0;i<6;i++)
		pdevice->PhysicalAddress[i] = mac_addr[i];

	/* Bring MAC out of Reset */

	/* Enable CLocks */

	MACREG( pdevice->pAU1000EnReg, MAC_ENABLE) =	SET(MAC_ENABLE_MACCLK) | 
													SET(MAC_ENABLE_DMARESET);

	/* Bring out of reset */

	MACREG( pdevice->pAU1000EnReg, MAC_ENABLE) =	SETV(3, MAC_ENABLE_IPG_MIN) |
													SET(MAC_ENABLE_TXEN) |
													SET(MAC_ENABLE_MIIENAB) |
													SET(MAC_ENABLE_MACINIT) |
													SET(MAC_ENABLE_MACCLK);

	/* Turn off promiscuous mode - other than that defaults should be OK */
	

	MACREG( pdevice->pAU1000CtrlRegs, MAC_CONTROL) = SETV(0, MAC_CONTROL_PR) |
#ifdef EB
													 SET(MAC_CONTROL_EM) |  /* Big Endian */
#endif
													 SET(MAC_CONTROL_DO) |   /* Disable Receive Own */
													 SET(MAC_CONTROL_DB);    /* Disable Broadcast Frames */	

	/* Program Address - The LSB of low address is the first bit to compare on receive
						 so this needs to contain the first byte to be compared */

	MACREG( pdevice->pAU1000CtrlRegs, MAC_ADDRLO) = pdevice->PhysicalAddress[0] 	 |
														pdevice->PhysicalAddress[1] << 8 |
														pdevice->PhysicalAddress[2] << 16|
														pdevice->PhysicalAddress[3] << 24;

	MACREG( pdevice->pAU1000CtrlRegs, MAC_ADDRHI) = pdevice->PhysicalAddress[4] |
														pdevice->PhysicalAddress[5] << 8;
	return( OK );
}


/************************************************************************
 *
 *                          MAC_AU1000_DMA_init
 *  Description :
 *  -------------
 *    Setup the AU1000 DMA registers
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  'pdevice',     IN,    reference for this device  context
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *
 *
 *
 ************************************************************************/
static
INT32 MAC_AU1000_DMA_init( t_MAC_AU1000_device *pdevice )		   
{
	int i;

	/* The DMA registers will not be clobbered in reset. The MAC registers will be */
	/* This means the DMA can be setup before the MAC is brought out of reset but the 
	   MAC can not be */

	/* Get next buffer location for DMA before setting EN=1 */

	pdevice->NextRcvBufferIndex = (MACREG( pdevice->pAU1000DMARegs, 
									SETV(DMA_RECEIVE, MAC_DMA_TXRX) |		
									SETV(DMA_ADDRESS_EN,MAC_DMA_REG)) & 
									MAC_DMA_NEXTBUF_MASK) >> MAC_DMA_NEXTBUF;

	/*	 Setup DMA Address for Rx  */

	for (i=0; i< MAC_AU1000_RX_BUFFERS ; i++) {
		
		MACREG( pdevice->pAU1000DMARegs, 
			SETV(DMA_RECEIVE, MAC_DMA_TXRX) |			
			SETV(i,MAC_DMA_BUF)  |				/* i selects buffer */
			SETV(DMA_ADDRESS_EN ,MAC_DMA_REG)  )		
			|= pdevice->RcvBuffer[i] & MAC_DMA_ADDR_MASK;  /* only upper 27 bits are used */
	}
																
	return( OK );
}




/************************************************************************
 *      Implementation : Device driver services
 ************************************************************************/



/************************************************************************
 *
 *                          MAC_AU1000_init
 *  Description :
 *  -------------
 *  This service initializes the lan driver and configures
 *  the MAC-address for the 'EN0' LAN interface.
 *  The MAC-address is read during 'init' via the 'syscon' parameter:
 *    -'SYSCON_COM_EN0_MAC_ADDR_ID'.
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  'major',     IN,    major device number
 *  'minor',     IN,    not used
 *  'p_param',   INOUT, not used
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *
 *
 *
 ************************************************************************/
static
INT32 MAC_AU1000_init(
		  UINT32 major, 		 /* IN: major device number 			*/
		  UINT32 minor, 		 /* IN: minor device number 			*/
		  void	 *p_param ) 	 /* INOUT: device parameter block		*/
{
	INT32 rcode;
	int i;
	UINT32	prid;

	prid = CP0_prid_read();

	if ((prid & 0xFF000000) == 0x00000000 ) // Au1000
	{
		if (minor == MAC0_MINOR_AU1000_DEVICE)
		{
			minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
			minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
			minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
		}
		else if (minor == MAC1_MINOR_AU1000_DEVICE)
		{
			minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC1_AU1000_BASE;
			minor_device[minor].pAU1000EnReg = (UINT32*) MAC1_AU1000_EN_BASE;
			minor_device[minor].pAU1000DMARegs = (UINT32*) MAC1_AU1000_DMA_BASE;
		}
	}
	else if ((prid & 0xFF000000) == 0x02000000 ) // Au1100
	{
		minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
		minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
		minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
	}
	else if ((prid & 0xFF000000) == 0x03000000 ) // Au1550
	{
		if (minor == MAC0_MINOR_AU1000_DEVICE)
		{
			minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
			minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
			minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
		}
		else if (minor == MAC1_MINOR_AU1000_DEVICE)
		{
			minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC1_AU1000_BASE;
			minor_device[minor].pAU1000EnReg = (UINT32*) MAC1_AU1000_EN_BASE;
			minor_device[minor].pAU1000DMARegs = (UINT32*) MAC1_AU1000_DMA_BASE;
		}
	}
	else if( (prid & 0xff000000) == 0x01000000 ) // if running on Au1500
	{
		if (minor == MAC0_MINOR_AU1000_DEVICE)
		{
			minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC0_AU1000_BASE;
			minor_device[minor].pAU1000EnReg = (UINT32*) MAC0_AU1000_EN_BASE;
			minor_device[minor].pAU1000DMARegs = (UINT32*) MAC0_AU1000_DMA_BASE;
		}
		else if (minor == MAC1_MINOR_AU1000_DEVICE)
		{
			minor_device[minor].pAU1000CtrlRegs = (UINT32*) MAC1_AU1000_BASE;
			minor_device[minor].pAU1000EnReg = (UINT32*) MAC1_AU1000_EN_BASE;
			minor_device[minor].pAU1000DMARegs = (UINT32*) MAC1_AU1000_DMA_BASE;
		}
		
		
		(long)(minor_device[minor].pAU1000CtrlRegs) |= Au1500_PBUS1_OFFSET;
		(long)(minor_device[minor].pAU1000EnReg) |= Au1500_PBUS1_OFFSET;
	}

#ifdef	ETH_DEBUG
	sprintf( msg, "\n\r MAC_AU1000_init: %08x\n\r", (UINT32) minor_device[minor].pAU1000CtrlRegs ) ;
	PUTS( DEFAULT_PORT, msg ) ;
#endif


	/* allocate MAC RX/TX frame buffer space */
	IF_ERROR( (rcode), 
			  (MAC_AU1000_allocate_buffers(&minor_device[minor])) )

		/* Stop any active DMA */
	IF_ERROR( (rcode), 
			 (MAC_AU1000_stop(&minor_device[minor])) )

	/* Reset MAC out of reset and program address */
	IF_ERROR( (rcode), 
			  (MAC_AU1000_control_init(&minor_device[minor])) ) 


	/* initialize AU1000 DMA context registers */
	IF_ERROR( (rcode), 
			  (MAC_AU1000_DMA_init(&minor_device[minor])) ) 

	/* initialize AU1000 MII */
	IF_ERROR( (rcode), 
			  (MAC_AU1000_MII_init(&minor_device[minor])) )

	/* Enable All 4 Receive DMA Here */

	/* Revise: Since all processing is polled,	we are assuming that receives will be solicited and
	will not occur at unknown times, this is an assumption	*/

	for (i=0; i< MAC_AU1000_RX_BUFFERS ; i++) {
		
		MACREG( minor_device[minor].pAU1000DMARegs, 
			SETV(DMA_RECEIVE, MAC_DMA_TXRX) |			
			SETV(i,MAC_DMA_BUF)  |				/* i selects buffer to enable */
			SETV(DMA_ADDRESS_EN ,MAC_DMA_REG)  )		
			|= MAC_DMA_ENABLE_MASK;
	}


	/* Enable TX and RX */
	MACREG( minor_device[minor].pAU1000CtrlRegs, MAC_CONTROL ) |= SET(MAC_CONTROL_TE) | SET(MAC_CONTROL_RE);


#ifdef	ETH_DEBUG
	/* dump AU1000 LAN controller registers */
	IF_ERROR( (rcode), 
			  (MAC_AU1000_dump_regs(&minor_device[minor])) )
#endif

	MAC_AU1000_state = MAC_AU1000_DRIVER_IS_STARTED;

	return( OK ) ;
}


/************************************************************************
 *
 *                          MAC_AU1000_open
 *  Description :
 *  -------------
 *  This service registers a mac-layer defined receive-handler in the
 *  LAN-drivers ISR-context to allow for interrupt controlled receive
 *  frame processing in the network stack. No external buffer
 *  administration is required as the protocol-layers are responsible for
 *  handling buffer-allocation and data copy-ing to the allocated buffer
 *  payload area. At return from 'receive' handler, the LAN-drivers
 *  local RX-buffer (packet) is released for re-use. After 'open'
 *  has been called, the LAN-driver's 'read' service will call the
 *  registered receive-handler by any frame reception with direct
 *  reference to the LAN-drivers packet space and no read data will be
 *  delivered in the IO-descriptor.
 *
 *
 *
 *  Parameters :
 *  ------------
 *
 *  'major',     IN,    major device number
 *  'minor',     IN,    not used
 *  'p_param',   IN,    LAN variable of type, t_LAN_IO_desc.
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0)
 *
 *
 *
 ************************************************************************/
static
INT32 MAC_AU1000_open(
		  UINT32 major, 		 /* IN: major device number 			*/
		  UINT32 minor, 		 /* IN: minor device number 			*/
		  t_LAN_OPEN_desc *p_param )   /* IN: receive handler reference */
{
	/* register user defined receive handler */
	usr_receive = p_param->receive ;

	return( OK ) ;
}



/************************************************************************
 *
 *                          MAC_AU1000_read

⌨️ 快捷键说明

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