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

📄 mac_init.c

📁 开发Inetl IXP2400平台所必须的硬件诊断和测试程序。该软件包支持的功能包括CPU基本功能检测
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *-------------------------------------------------------------------------------
 *                                                                      
 *                  I N T E L   P R O P R I E T A R Y                   
 *                                                                      
 *     COPYRIGHT (c)  2002 BY  INTEL  CORPORATION.  ALL RIGHTS          
 *     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY      
 *     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A    
 *     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER    
 *     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,    
 *     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT    
 *     THE PRIOR WRITTEN PERMISSION OF :                                
 *                                                                      
 *                        INTEL  CORPORATION                            
 *                                                                     
 *                     2200 MISSION COLLEGE BLVD                        
 *                                                                      
 *               SANTA  CLARA,  CALIFORNIA  95052-8119                  
 *                                                                      
 * ------------------------------------------------------------------------------
 */

/**
 * User defined include files required.
 */
#include "diag.h"
#include "mac_init.h"
#include "error_map.h" 
#include "register_map.h"
#include "reg_api.h"
#include "common.h"
#include "diagstruct.h"
/**
 * Pre-processor symbols and macros used in this file.
 */

#define PLL_LOCK_TIMER		50		/* Check PLL lock register 50 times 
                                   	   with a delay of 1ms */

#define PHY_REG_ADDRESS          0x1F
#define PHY_DEVICE_ADDRESS       0x03
#define PHY_DEVICE_SHIFT         0x08
#define PHY_READ                 0x120000
#define PHY_WRITE                0x110000
#define DEFAULT_SET              0x01

#define NUM_PHY_REGS			0x1F


/**
 * Variable declarations global to this file only.  Externs are followed by
 * static variables.
 */

    static configData aMacResetConfigTbl[ ] = 
    {
        {MAC_SOFT_RESET,        0x0000000F, 1},
        {TXFIFO_PORT_RESET,     0x0000000F, 1},         
        {RXFIFO_PORT_RESET,     0x0000000F, 1},
        {SPI3_TX_GLOBAL_CONFIG, 0x00E00000, 1}         
        //{MDIO_RESET,            0x00000001, 1}
    };

#define MacResetConfigTblSz (sizeof(aMacResetConfigTbl) /sizeof(aMacResetConfigTbl[0]))

    static configData aMacDisableResetConfigTbl[] =
    {
        {MAC_SOFT_RESET,        0x00000000, 1},
        {TXFIFO_PORT_RESET,     0x00000000, 1},
        {RXFIFO_PORT_RESET,     0x00000000, 1},
        {MDIO_RESET,            0x00000000, 1},
        {SERDES_CLKMODE_REG,    0x0000000F, 1},
        {PORT_ENABLE,           0x0000000F, 1}
    };

#define MacDisableResetConfigTblSz (sizeof(aMacDisableResetConfigTbl) /sizeof(aMacDisableResetConfigTbl[0]))


/**
 * Extern function prototypes.
 */

extern UINT32 reg_read( volatile UINT32 offset);
extern void reg_write( volatile UINT32 offset, UINT32 val);
extern void hal_delay_us(unsigned int usecs);
extern void eprintf(char *f, ...);
extern void gets(char *str, int len);
extern void Disable_CPSR_Int(void);
extern void Enable_CPSR_Int(void);
extern short check_autoneg_status(void);
extern UINT32 cu_init(UINT32 set_int_lpbk);
extern int getCmdLine(char* cmdLine);

/** local functions **/
void gbe_mac_phy_write(UINT32 arg_PhyAddress,UINT32 arg_RegAddress,UINT32 arg_WriteValue);
UINT32 gbe_mac_phy_read(UINT32 arg_PhyAddress, UINT32 arg_RegAddress);
void fiber_init(void);
void mixed_mode_init(UINT32 set_int_lpbk);
void mixed_mode_init1(UINT32 set_int_lpbk);
unsigned int htoi(char *s);
int ctoi(char c);
void check_error_display_txstats(void);
void gets(char *str, int len);

/* Globals */
extern UINT32 loop,speed;  
extern char channel,test_opt,dplx, loopback_mode;
extern UINT32 media_seat;
extern UINT32 silicon_rev;

UINT32 orig_sp_val[8];
UINT32 cport=0;
UINT32 mdio_enabled = 0;
UINT32 sf_mdio_enabled = 0;
extern UINT32 rxstat[4][30],txstat[4][30];
extern UINT32 ports;
/**
 * Function definitions.
 */

    UINT32 init_mac_dev (UINT32 set_int_lpbk) 
    {
 
     	UINT32 pll_lock_status =0;
        UINT32 pll1_tuning_status,pll2_tuning_status,pll3_tuning_status =0;
		UINT32 total_delay=0, status=0, ctr=0;
	
		/* configure slow port in mode 3 */
        spConfig();

        pll_lock_status=reg_read(SERDES_PLL_LOCK_STATUS);
		pll1_tuning_status= reg_read(PLL1_TUNE_REG); 
		pll2_tuning_status= reg_read(PLL2_TUNE_REG); 
		pll3_tuning_status= reg_read(PLL3_TUNE_REG); 
        
	eprintf("Waiting for PLL Lock to set...\n");
	
	do
        {
            hal_delay_us(1000);		/* delay of 1 ms */

            pll_lock_status=reg_read(SERDES_PLL_LOCK_STATUS);
			pll1_tuning_status= reg_read(PLL1_TUNE_REG); 
			pll2_tuning_status= reg_read(PLL2_TUNE_REG); 
			pll3_tuning_status= reg_read(PLL3_TUNE_REG); 
			if ( (pll1_tuning_status != 0x534) || (pll2_tuning_status != 0x534) || (pll3_tuning_status != 0x5be) )
            {
				eprintf("pll1_tuning_status=0x%08X\n", pll1_tuning_status);
				eprintf("pll2_tuning_status=0x%08X\n", pll2_tuning_status);
				eprintf("pll3_tuning_status=0x%08X\n", pll3_tuning_status);
				eprintf("Pll Tuning register lock failed !\n");
				return ABORT;
			}

//	    MSG("PLL lock 0x%x\n",pll_lock_status,0,0);
//	    MSG("PLL lock 0x%x\n",pll1_tuning_status,0,0);
//	    MSG("PLL lock 0x%x\n",pll2_tuning_status,0,0);
//	    MSG("PLL lock 0x%x\n",pll3_tuning_status,0,0);

            total_delay ++;
            if (total_delay > PLL_LOCK_TIMER)
            {
                eprintf("PLL Lock Timer : Timed out\n");
				eprintf("pll1_tuning_status=0x%08X\n", pll1_tuning_status);
				eprintf("pll2_tuning_status=0x%08X\n", pll2_tuning_status);
				eprintf("pll3_tuning_status=0x%08X\n", pll3_tuning_status);
				eprintf("pll_lock_status=0x%08X\n", pll_lock_status);
				return PLL_LOCK_ERR;
            }
        }
		while(pll_lock_status != 0x3);


		switch (channel)
		{
			case 'f' :
			case 'F' : 
		    			eprintf("\nConfiguring Fiber Channels ..\n");	
		    			fiber_init();	/** configure the device in fiber mode **/
						break;
	
			case 'c' :
			case 'C' : 
				        eprintf("\nConfiguring Copper Channels ..\n");	       	
		    			status=cu_init(set_int_lpbk);
						break;

	         case 'm' :
             case 'M' :
                     	if (cport == 0)
						{
                    		eprintf("\nConfiguring channel 0,1 in Copper and 2, 3 in Fiber ..\n");
						}
						else if (cport == 2)
						{
                    		eprintf("\nConfiguring channel 0,1 in Fibre and 2, 3 in Copper ..\n");
						}
						mixed_mode_init(set_int_lpbk);
						break;

            case 'n' :
            case 'N' :
						eprintf("\nConfiguring chaneel 2,3 in Copper and 0, 1 in Fiber ..\n");
						mixed_mode_init1(set_int_lpbk);
                    	break;

		    	default :	//eprintf("\nIllegal Channel option.. configuring fiber as default. \n");	
		    			fiber_init();	/** configure the device in fiber mode **/
					break;
		}

		if (status == ABORT)
			return ABORT;
	
        /* apply delay of 1 second for clock stabilization */
        hal_delay_us(1000000);    

		/* configure station addresses */
		
		reg_write((STATION_ADDR_LOW), 0xA0A0A0A0);
		reg_write((STATION_ADDR_HIGH),0x00A0);
	
		reg_write((STATION_ADDR_LOW + 0x80), 0xB0B0B0B0);
		reg_write((STATION_ADDR_HIGH + 0x80),0x00B0);
	
		reg_write((STATION_ADDR_LOW + 0x100), 0xC0C0C0C0);
		reg_write((STATION_ADDR_HIGH + 0x100),0x00C0);
		
		reg_write((STATION_ADDR_LOW + 0x180), 0xD0D0D0D0);
		reg_write((STATION_ADDR_HIGH + 0x180),0x00D0);
		
		/* 48-bit globally assigned multicast pause frame destination address */
		reg_write((MUL_PORT_ADDR_LOW), 0xA0A0A0A0);
		reg_write((MUL_PORT_ADDR_HIGH), 0xA1A0);
	
		reg_write((MUL_PORT_ADDR_LOW + 0x80), 0xB0B0B0B0);
		reg_write((MUL_PORT_ADDR_HIGH + 0x80), 0xA1B0);
	
		reg_write((MUL_PORT_ADDR_LOW + 0x100), 0xC0C0C0C0);
		reg_write((MUL_PORT_ADDR_HIGH + 0x100), 0xA1C0);
	
		reg_write((MUL_PORT_ADDR_LOW + 0x180), 0xD0D0D0D0);
		reg_write((MUL_PORT_ADDR_HIGH + 0x180), 0xA1D0);

		for(ctr=0;ctr<4;ctr++)
		{
			/* Tx FIFO high watermark */
			reg_write((PORT0_TX_HIGH_WATERMARK + ctr), 0x3E0);
			/* Tx FIFO low watermark */
			reg_write((PORT0_TX_LOW_WATERMARK + ctr), 0xD0);
			/* Tx FIFO MAC threshold */
			reg_write((PORT0_TX_MAC_THRESHOLD + ctr), 0x1BE);

			/* Rx FIFO high watermark */
			reg_write((PORT0_RX_HIGH_WATERMARK + ctr), 0x0E6);
			/* Rx FIFO low watermark */
			reg_write((PORT0_RX_LOW_WATERMARK + ctr), 0x072);

		}
		spRestore();	
        return DONE;
    }   

    void mac_disable_reset(void)
    {
        short i=0;

        for (i=0;i<MacDisableResetConfigTblSz; i++)
        {
            reg_write((aMacDisableResetConfigTbl[i].reg_addr), aMacDisableResetConfigTbl[i].config_val);
        }
    }

    void mac_reset_config(void)
    {
        short i=0;

        for (i=0;i<MacResetConfigTblSz; i++)
        {
            reg_write(aMacResetConfigTbl[i].reg_addr, aMacResetConfigTbl[i].config_val);
        }
    }

void config_phy_for_line_lpbk(void)
{
	short port_ctr = 0;

	for (port_ctr=0;port_ctr<4; port_ctr++)
	{
			//gbe_mac_phy_write(port_ctr, 0x1B, 0x105);	/* Set LED Control in PHY */
            gbe_mac_phy_write(port_ctr, 0x19, 0xB400);	/* Enable all interrupts */
	        gbe_mac_phy_write(port_ctr, 0x17, 0x1300);	// Enable RGMII mode
			if (speed == 1000)
				gbe_mac_phy_write(port_ctr, 0x9, 0x300);		/* set gigabit operation */

			gbe_mac_phy_write(port_ctr, 0, 0x1240);		// set auto-neg
	}
}


UINT32 config_phy(void)
{
	int s_PortCount =0;
	UINT32 status=0;
 
	for(s_PortCount=0; s_PortCount<4;s_PortCount++)
    {		
			//gbe_mac_phy_write(s_PortCount, 0x1B, 0x105);	/* Set LED Control in PHY */
            gbe_mac_phy_write(s_PortCount, 0x19, 0xB400);	/* Enable all interrupts */
	        gbe_mac_phy_write(s_PortCount, 0x17, 0x1300);	// Enable RGMII mode

	    switch (speed)
	    {
		case 1000 :	//eprintf("configuring 1000 \n");
				switch(dplx)
				{
					case 'h':
						gbe_mac_phy_write(s_PortCount, 0x4, 0x0);
						gbe_mac_phy_write(s_PortCount, 0x9, 0x100);		/* set gigabit operation */
						gbe_mac_phy_write(s_PortCount, 0, 0x1240); 
						gbe_mac_phy_write(s_PortCount, 22, 0x2018); 
						gbe_mac_phy_write(s_PortCount, 24, 0x3248); 
						//gbe_mac_phy_write(s_PortCount, 0, 0x1040);
						break;
					case 'f':
						gbe_mac_phy_write(s_PortCount, 0x4, 0x0);
						gbe_mac_phy_write(s_PortCount, 0x9, 0x300);		/* set gigabit operation */
						gbe_mac_phy_write(s_PortCount, 0, 0x1240); 
						gbe_mac_phy_write(s_PortCount, 22, 0x18); 
						gbe_mac_phy_write(s_PortCount, 24, 0x3248); 
						break;
				}
						     		       		
	 			//gig_config();
				break;
		case 100:
				//eprintf("configuring 100 \n");		
			        switch(dplx)
	        		{
		    			case 'h' :  //gbe_mac_phy_write(s_PortCount, 0, 0x1240);    
									gbe_mac_phy_write(s_PortCount, 0x4, 0x80);    
									gbe_mac_phy_write(s_PortCount, 0x9, 0x400); 
									gbe_mac_phy_write(s_PortCount, 0, 0x1240); 
									//gbe_mac_phy_write(s_PortCount, 0, 0x2000);
				    				break;
		    			case 'f' :  //gbe_mac_phy_write(s_PortCount, 0, 0x1240);
									gbe_mac_phy_write(s_PortCount, 0x4, 0x180);    
									gbe_mac_phy_write(s_PortCount, 0x9, 0x400); 
									gbe_mac_phy_write(s_PortCount, 0, 0x1240);
									//gbe_mac_phy_write(s_PortCount, 0, 0x2100);
				    				break;
	        		}		
				break;

		case 10:
				//eprintf("configuring 10 \n");						
			        switch(dplx)
	        		{
		    			case 'h' : 		//gbe_mac_phy_write(s_PortCount, 0, 0x1240);
										gbe_mac_phy_write(s_PortCount, 0x4, 0x60);    
										gbe_mac_phy_write(s_PortCount, 0x9, 0x400); 
										gbe_mac_phy_write(s_PortCount, 0, 0x1240);
										//gbe_mac_phy_write(s_PortCount, 0, 0x0);
										break;
		    			case 'f' :		//gbe_mac_phy_write(s_PortCount, 0, 0x1240);
										gbe_mac_phy_write(s_PortCount, 0x4, 0x40);    
										gbe_mac_phy_write(s_PortCount, 0x9, 0x400);   
										gbe_mac_phy_write(s_PortCount, 0, 0x1240);
										//gbe_mac_phy_write(s_PortCount, 0, 0x0100);
				    					break;
	        		}		
				break;

		default : 	eprintf("Bad speed option ... configuring 100 Mbps speed.\n");
				//eprintf("configuring 100 \n");		
			        switch(dplx)
	        		{
		    			case 'h' :      gbe_mac_phy_write(s_PortCount, 0, 0x2000);
				    			break;
		    			case 'f' :      gbe_mac_phy_write(s_PortCount, 0, 0x2100);
				    			break;
	        		}		
				break;
	    	}
        }

	if (channel == 'm')
	{
		check_autoneg_status_mixed_mode();
	}
	else
	{
		status = check_autoneg_status();
	}
	if (status == ERROR)
	{
		eprintf("Auto-negotiation FAILED \n");
		return ABORT;
	}
	return DONE;
}

void gbe_mac_phy_write( UINT32 arg_PhyAddress,
                               UINT32 arg_RegAddress,
                               UINT32 arg_WriteValue
                              )
{
    UINT32 s_ReadValue;
    UINT32 s_WriteValue = 0;
    UINT32 s_RegAddress, s_PhyAddress;
    UINT32 mdio_done = 0;
    UINT32 ctr=0;

	if(((!media_seat) && (!mdio_enabled)) || ((media_seat) && (!sf_mdio_enabled)))
	{
		reg_write(MDIO_CTL,0x6); 	// enable mdi and autoscan
		
		s_ReadValue = reg_read((unsigned int)MDIO_CTL);
		s_ReadValue = s_ReadValue >> 3;
		s_ReadValue &= DEFAULT_SET;
		mdio_done = s_ReadValue;
		while(mdio_done != 0)
		{
			ctr++;
			hal_delay_us(10000);
			if (ctr > 5)
			{
				eprintf("ERROR: COULD NOT PERFORM MDIO READ\n");
				return;
			}
			s_ReadValue = reg_read((unsigned int)MDIO_CTL);
			s_ReadValue = s_ReadValue >> 3;
			s_ReadValue &= DEFAULT_SET;
			mdio_done = s_ReadValue;
		}
		ctr = 0;
		if(media_seat)
		{
			sf_mdio_enabled = 1;
		}
		else
		{
			mdio_enabled = 1;
		}
	}

    s_RegAddress = arg_RegAddress & PHY_REG_ADDRESS;
	s_PhyAddress = arg_PhyAddress & PHY_DEVICE_ADDRESS;
	s_PhyAddress = s_PhyAddress << PHY_DEVICE_SHIFT;
	
	s_WriteValue = s_PhyAddress | s_RegAddress;
	s_WriteValue = s_WriteValue | PHY_WRITE;
	
	reg_write(MDIO_SINGLE_RW_DATA,arg_WriteValue);  // write value to be programmed in phy
	
	reg_write(MDIO_SNGL_CMD, s_WriteValue);        // write command to mdio
	
	s_ReadValue = reg_read((unsigned int)MDIO_SNGL_CMD);
	
	s_ReadValue = s_ReadValue >> 20;
	s_ReadValue &= DEFAULT_SET;
	mdio_done = s_ReadValue;
	
	while (mdio_done != 0)
	{
		ctr++;
		hal_delay_us(10000);
		if (ctr > 5)
		{
			eprintf("ERROR: COULD NOT PERFORM MDIO WRITE\n");
			break;
		}
		s_ReadValue = reg_read((unsigned int)MDIO_SNGL_CMD);
		s_ReadValue = s_ReadValue >> 20;
		s_ReadValue &= DEFAULT_SET;
		mdio_done = s_ReadValue;
	}
}

void gbe_mac_phy_read_all()
{
    short i=0;
    short phy = 0;
	char inp[2],p;
	register PDiagCommon acL = (PDiagCommon) ACADDRESS;

	if(acL->argv[3][0] == 's')
	{
		media_seat = 0xBABECAFE;
	}

	eprintf("Enter phy no (0-3) :\n");
	gets(inp,2);
	p = inp[0];

	switch (p)
	{
		case '0' :	phy = 0;
					break;
		case '1':	phy = 1;
					break;
		case '2' :	phy = 2;
					break;
		case '3' :	phy = 3;
					break;
		default :	phy = 0;
					break;
	}

	eprintf("Reading PHY %d Registers \n",phy);
	eprintf("------------------------\n");
    eprintf("\n Reg Number \t\t	Value\n");
    
    for (i=0;i<=NUM_PHY_REGS;i++)
    {
		eprintf("0x%x \t\t  0x%x\n", i, gbe_mac_phy_read(phy, i));
    }
	media_seat = 0;
}

UINT32 gbe_mac_phy_read( UINT32 arg_PhyAddress,
                         UINT32 arg_RegAddress)
		
{
    UINT32 s_ReadValue;
    UINT32 s_WriteValue = 0;
    UINT32 s_RegAddress, s_PhyAddress;
    UINT32 mdio_done = 0;
    UINT32 ctr=0;
    short phy = arg_PhyAddress;

⌨️ 快捷键说明

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