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

📄 lepus_gmac_phy.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** Copyright  Storlink Corp 2005.  All rights reserved.                *--------------------------------------------------------------------------* Name			: emac_phy.c* Description	: *		Handle Ethernet PHY and MII interface** History**	Date		Writer		Description*	-----------	-----------	-------------------------------------------------*	08/16/2005	Gary Chen	Create and implement from Amos Linux Code*****************************************************************************/#include <define.h>#include <board_config.h>#include <sl2312.h>#if defined(MIDWAY) && (defined(LEPUS_FPGA) || defined(LEPUS_ASIC))#include "sl_lepus_gmac.h"//extern unsigned int FLAG_SWITCH;unsigned int mii_read(unsigned char phyad,unsigned char regad);void mii_write(unsigned char phyad,unsigned char regad,unsigned int value);extern void gmac_write_reg(unsigned int base, unsigned int offset,unsigned int data,unsigned int bit_mask);extern void toe_gmac_disable_tx_rx(void);//(GMAC_INFO_T *tp);extern void toe_gmac_enable_tx_rx(void);//(GMAC_INFO_T *tp);void gmac_get_phy_status(GMAC_INFO_T *tp);extern unsigned int gmac_read_reg(unsigned int base, unsigned int offset);extern void gmac_write_reg(unsigned int base, unsigned int offset,unsigned int data,unsigned int bit_mask);extern gmac_num;int switch_pre_speed[5]={0,0,0,0,0};int switch_pre_link[5]={0,0,0,0,0};unsigned int switch_status;void gmac_set_phy_status(GMAC_INFO_T *tp){		GMAC_STATUS_T   status;	unsigned int    reg_val, ability ,rcv_mask;	unsigned int    i = 0;		if(gmac_num)	{#if 0				switch_status = LINK_DOWN;		rcv_mask = SPI_read(2,0,0x10);			// Receive mask		rcv_mask |= 0x4F;		for(i=0;i<4;i++){			reg_val = BIT(26)|(i<<21)|(10<<16);			SPI_write(3,0,1,reg_val);			hal_delay_us(10*1000);			reg_val = SPI_read(3,0,2);			if(reg_val & 0x0c00){				//printf("Port%d:Giga mode\n",i);				SPI_write(1,i,0x00,0x300701b1);					SPI_write(1,i,0x00,0x10070181);					switch_pre_link[i]=LINK_UP;				switch_pre_speed[i]=GMAC_SPEED_1000;			}			else{				reg_val = BIT(26)|(i<<21)|(5<<16);				SPI_write(3,0,1,reg_val);				hal_delay_us(10*1000);				ability = (reg_val = SPI_read(3,0,2)&0x5e0) >>5;				if ((ability & 0x0C)) /* 100M full duplex */				{					SPI_write(1,i,0x00,0x30050472);						SPI_write(1,i,0x00,0x10050442);						//printf("Port%d:100M\n",i);					switch_pre_link[i]=LINK_UP;				switch_pre_speed[i]=GMAC_SPEED_100;				}				else if((ability & 0x03)) /* 10M full duplex */				{					SPI_write(1,i,0x00,0x30050473);						SPI_write(1,i,0x00,0x10050443);						//printf("Port%d:10M\n",i);					switch_pre_link[i]=LINK_UP;					switch_pre_speed[i]=GMAC_SPEED_10;				}				else{					SPI_write(1,i,0x00,0x20000030);			// PORT_RST					switch_pre_link[i]=LINK_DOWN;					switch_pre_speed[i]=GMAC_SPEED_10;					rcv_mask &= ~BIT(i);					SPI_write(2,0,0x10,rcv_mask);			// Disable Receive				}			}		}		SPI_write(2,0,0x10,rcv_mask);			// Enable Receive#endif		gmac_get_phy_status(tp);				gmac_write_reg(tp->base_addr, GMAC_STATUS, 0x7d, 0x0000007f);			}	else	{		   // if (FLAG_SWITCH==1)	   // {	   //     return; /* GMAC connects to a switch chip, not PHY */	   // }	    reg_val=(mii_read(tp->phy_addr,0x02) << 16) + mii_read(tp->phy_addr,0x03);	    printf("PHY %d Addr %d Vendor ID: 0x%08x\n", tp->phy_id, tp->phy_addr, reg_val);		#if defined(GEMINI_ASIC) || defined(LEPUS_ASIC)		mii_write(tp->phy_addr,0x04,0x05e1); 		mii_write(tp->phy_addr,0x09,0x0300);	#else	   	mii_write(tp->phy_addr,0x04,0x05e1); /* advertisement 100M full duplex, pause capable on */	   	mii_write(tp->phy_addr,0x09,0x0000); /* advertisement no 1000M */	#endif    	    mii_write(tp->phy_addr,0x00,0x1200);			reg_val = 0x1200 | (1 << 15);		mii_write(tp->phy_addr,0x00,reg_val); /* Enable and Restart Auto-Negotiation */		reg_val &= ~(1 << 15);		mii_write(tp->phy_addr, 0x00, reg_val);		hal_delay_us(100000);#if 1	// SJC		if (1) {			unsigned int	reg_val;			reg_val = mii_read(tp->phy_addr, 0x18);			reg_val |= 1;			mii_write(tp->phy_addr, 0x18, reg_val);		}#endif	}	gmac_get_phy_status(tp);}void gmac_get_phy_status(GMAC_INFO_T *tp){	GMAC_CONFIG0_T	config0,config0_mask;    GMAC_STATUS_T   status, old_status;    unsigned int    reg_val,ability;    unsigned int    dev_index,rcv_mask,mac_config,speed_fdx_mode,link_mode=0;	int i;			if(gmac_num)	{				rcv_mask = SPI_read(2,0,0x10);			// Receive mask				old_status.bits32 = status.bits32 = gmac_read_reg(tp->base_addr, GMAC_STATUS);		for(i=0;i<4;i++){			//if(((phy_read(i, 1) & 0x0004) != 0))			//{			//		printf("Port %x link up\n",i);			//					//		/* Get info about speed and duplex mode from PHY reg. 28 */     		//		reg_val = phy_read(i, 28);
   		//			    		//		/* set speed field (bit 1:0) = bit 4:3 of PHY reg. */    		//		speed_fdx_mode = ((unsigned char) reg_val >> 3) & 0x03;
   		//		    		//		/* update full duplex bit */    		//		if (reg_val & 0x20) {    		//		    speed_fdx_mode |= 0x10;    		//		}    		//		    		//		    		//		/* check if link partner supports pause frames */    		//		if (phy_read(i, 5) & 0x0400) {    		//		    link_mode |= 0x20;    		//		}    		//		printf("reg_val %x speed_fdx_mode %x link_mode %x\n",reg_val,speed_fdx_mode,link_mode);    		//}    					reg_val = BIT(26)|(i<<21)|(1<<16);			SPI_write(3,0,1,reg_val);			hal_delay_us(5*1000);			reg_val = SPI_read(3,0,2);			if ((reg_val & 0x0024) == 0x0024) /* link is established and auto_negotiate process completed */			{				if(switch_pre_link[i]==LINK_DOWN){		// Link Down ==> Link up												rcv_mask |= BIT(i);			// Enable receive								//reg_val = phy_read(i,28) ;				reg_val = BIT(26)|(i<<21)|(10<<16);				SPI_write(3,0,1,reg_val);				hal_delay_us(5*1000);				reg_val = SPI_read(3,0,2);				if(reg_val & 0x0c00){#if 0										printk("Port%d:Giga mode\n",i);					phy_optimize_receiver_reconfig(i);					SPI_write(1,i,0x00,0x300701B1);					SPI_write(1,i,0x00,0x10070181);					switch_pre_link[i]=LINK_UP;					switch_pre_speed[i]=GMAC_SPEED_1000;#else					//printk("Port%d:Giga mode\n",i);					//mac_config = 0x00060004;					mac_config = 0x00060184;										SPI_write(1,i,0x00,((mac_config & 0xfffffff8) | 1) | 0x20000030);	// reset port					mac_config |= (( BIT(i) << 19) | 0x08000000);					SPI_write(1,i,0x00,mac_config);					SPI_write(1,i,0x04,0x000300ff);		// flow control										reg_val = SPI_read(5,0,0x12);					reg_val &= ~BIT(i);					SPI_write(5,0,0x12,reg_val);										reg_val = SPI_read(1,i,0x00);					reg_val |= 0x18010000;					SPI_write(1,i,0x00,reg_val);										//phy_receiver_reconfig(i);					switch_pre_link[i]=LINK_UP;					switch_pre_speed[i]=GMAC_SPEED_1000;					#endif									}				else{					reg_val = BIT(26)|(i<<21)|(5<<16);					SPI_write(3,0,1,reg_val);					hal_delay_us(5 * 1000);					ability = (reg_val = SPI_read(3,0,2)&0x5e0) >>5;					if ((ability & 0x0C)) /* 100M full duplex */					{#if 0												SPI_write(1,i,0x00,0x30050472);						SPI_write(1,i,0x00,0x10050442);						printk("Port%d:100M\n",i);						switch_pre_link[i]=LINK_UP;						switch_pre_speed[i]=GMAC_SPEED_100;#else						//mac_config = 0x00040004;						mac_config = 0x00040444;											SPI_write(1,i,0x00,((mac_config & 0xfffffff8) | 1) | 0x20000030);	// reset port						mac_config |= (( BIT(i) << 19) | 0x08000000);						SPI_write(1,i,0x00,mac_config);						SPI_write(1,i,0x04,0x000300ff);		// flow control											reg_val = SPI_read(5,0,0x12);						reg_val &= ~BIT(i);						SPI_write(5,0,0x12,reg_val);											reg_val = SPI_read(1,i,0x00);						reg_val |= 0x18010000;						SPI_write(1,i,0x00,reg_val);						//printk("Port%d:100M\n",i);						switch_pre_link[i]=LINK_UP;						switch_pre_speed[i]=GMAC_SPEED_100;#endif											}					else if((ability & 0x03)) /* 10M full duplex */					{#if 0												SPI_write(1,i,0x00,0x30050473);						SPI_write(1,i,0x00,0x10050443);						printk("Port%d:10M\n",i);						switch_pre_link[i]=LINK_UP;						switch_pre_speed[i]=GMAC_SPEED_10;#else						mac_config = 0x00040004;											SPI_write(1,i,0x00,((mac_config & 0xfffffff8) | 1) | 0x20000030);	// reset port						mac_config |= (( BIT(i) << 19) | 0x08000000);						SPI_write(1,i,0x00,mac_config);						SPI_write(1,i,0x04,0x000300ff);		// flow control											reg_val = SPI_read(5,0,0x12);						reg_val &= ~BIT(i);						SPI_write(5,0,0x12,reg_val);											reg_val = SPI_read(1,i,0x00);						reg_val |= 0x18010000;						SPI_write(1,i,0x00,reg_val);						//printk("Port%d:10M\n",i);						switch_pre_link[i]=LINK_UP;						switch_pre_speed[i]=GMAC_SPEED_10;#endif											}					else{						SPI_write(1,i,0x00,0x20000030);						//printk("Port%d:Unknown mode\n",i);						switch_pre_link[i]=LINK_DOWN;						switch_pre_speed[i]=GMAC_SPEED_10;						}					}					arp_flush_cache();#if 0										reg_val = SPI_read(2,0,0x80+i);					reg_val &= ~BIT(i);					SPI_write(2,0,0x80+i,reg_val);#endif									}				else{						// Link up ==> Link UP							tp->pre_phy_status = LINK_UP;							}					if((tp->pre_phy_status == LINK_UP)&&(switch_status == LINK_DOWN))					{						//printf(" toe_gmac_enable_tx_rx 1: \n");						toe_gmac_enable_tx_rx();						switch_status = LINK_UP;					}			}			else{							// Link up ==> Link Down				if(switch_pre_link[i]==LINK_UP){#if 0										printk("Port%d:Link Down\n",i);					phy_optimize_receiver_init(i);					reg_val = SPI_read(1,i,0x00);								reg_val &= ~BIT(16);					SPI_write(1,i,0x00,reg_val);			// disable RX					SPI_write(5,0,0x0E,BIT(i));			// dicard packet					while((SPI_read(5,0,0x0C)&BIT(i))==0)			// wait to be empty						hal_delay_us(1*1000);										SPI_write(1,i,0x00,0x20000030);			// PORT_RST#else   						//printk("Port%d:Link Down\n",i);					phy_receiver_init(i);					reg_val = SPI_read(1,i,0);					reg_val &= ~BIT(16);					SPI_write(1,i,0x00,reg_val);			// disable RX					SPI_write(5,0,0x0E,BIT(i));			// dicard packet					while((SPI_read(5,0,0x0C)&BIT(i))==0)		// wait to be empty						hal_delay_us(1*1000);					SPI_write(1,i,0x00,0x20000030);			// PORT_RST										SPI_write(5,0,0x0E,SPI_read(5,0,0x0E)&~BIT(i));			// dicard packet					reg_val = SPI_read(5,0,0x12);					reg_val |= BIT(i);					SPI_write(5,0,0x12,reg_val);#endif									}#if 0								switch_pre_link[i]=LINK_DOWN;				rcv_mask &= ~BIT(i);			// disable receive				SPI_write(5,0,0x12,BIT(i));	#else   					switch_pre_link[i]=LINK_DOWN;				rcv_mask &= ~BIT(i);			// disable receive#endif							}		}			if((switch_pre_link[0]==LINK_DOWN)&&(switch_pre_link[1]==LINK_DOWN)&&(switch_pre_link[2]==LINK_DOWN)&&(switch_pre_link[3]==LINK_DOWN))			tp->pre_phy_status = LINK_DOWN;    	    						SPI_write(2,0,0x10,rcv_mask);			// Receive mask						if((tp->pre_phy_status == LINK_UP)&&(switch_status == LINK_DOWN))		{			//printf(" toe_gmac_enable_tx_rx: \n");			toe_gmac_enable_tx_rx();			switch_status = LINK_UP;		}		else if((tp->pre_phy_status == LINK_DOWN)&&(switch_status == LINK_UP)){			//printf("toe_gmac_disable_tx_rx\n");			toe_gmac_disable_tx_rx();			//arp_flush_cache();			switch_status = LINK_DOWN;		}			}	else //if(!gmac_num)	{		    			status.bits32 = old_status.bits32 = gmac_read_reg(tp->base_addr, GMAC_STATUS);    	    	/* read PHY status register */    	reg_val = mii_read(tp->phy_addr,0x01);    	if ((reg_val & 0x0024) == 0x0024) /* link is established and auto_negotiate process completed */    	{    	    /* read PHY Auto-Negotiation Link Partner Ability Register */    	    reg_val = mii_read(tp->phy_addr,10);    	    if ((reg_val & 0x0800) == 0x0800)

⌨️ 快捷键说明

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