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

📄 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*	-----------	-----------	-------------------------------------------------*	04/25/2005	Gary Chen	Create and implement from Jason's Redboot code*****************************************************************************/#include <define.h>#include <board_config.h>#include <sl2312.h>#ifdef MIDWAY#ifndef LEPUS_FPGA #ifndef LEPUS_ASIC#include "gmac_sl2312.h"#define diag_printf			printf/************************************************//*                 function declare             *//************************************************/unsigned int mii_read(unsigned char phyad,unsigned char regad);void mii_write(unsigned char phyad,unsigned char regad,unsigned int value);void gmac_set_phy_status(void);void gmac_get_phy_status(void);void outb(unsigned int addr, unsigned int value);unsigned char inb(unsigned int addr);/****************************************//*	SPI Function Declare		*//****************************************/void SPI_write(unsigned char addr,unsigned int value);unsigned int SPI_read(unsigned char table,unsigned char addr);void SPI_write_bit(char bit_EEDO);unsigned int SPI_read_bit(void);void SPI_default(int vlan_enabled);void SPI_reset(unsigned char rstype,unsigned char port_cnt);void SPI_pre_st(void);void SPI_CS_enable(unsigned char enable);void SPI_Set_VLAN(unsigned char LAN,unsigned int port_mask);void SPI_Set_tag(unsigned int port,unsigned tag);void SPI_Set_PVID(unsigned int PVID,unsigned int port_mask);unsigned int SPI_Get_PVID(unsigned int port);void SPI_mac_lock(unsigned int port, unsigned char lock);void SPI_get_port_state(unsigned int port);void SPI_port_enable(unsigned int port,unsigned char enable);unsigned int SPI_get_identifier(void);void SPI_get_status(unsigned int port);/****************************************//*	VLAN Function Declare		        *//****************************************/extern unsigned int FLAG_SWITCH;	/* if 1-->switch chip presented. if 0-->switch chip unpresented */extern unsigned int full_duplex;extern unsigned int chip_id;struct gmac_conf VLAN_conf[] = { #ifdef CONFIG_ADM_6999		{ (struct net_device *)0,0x7F,1 }, 	{ (struct net_device *)0,0x80,2 } #endif#ifdef CONFIG_ADM_6996	{ (struct net_device *)0,0x0F,1 }, 	{ (struct net_device *)0,0x10,2 } #endif};#define NUM_VLAN_IF	(sizeof(VLAN_conf)/sizeof(struct gmac_conf))/************************************************//*                 function body                *//************************************************/#define gmac_read_reg(offset)					REG32(GMAC_BASE_ADDR + offset)#define gmac_write_reg(offset, data, mask)		REG32(GMAC_BASE_ADDR + offset) = 	\												(gmac_read_reg(offset) & (~mask)) | \												(data & mask)#define readl(addr)								REG32(addr)#define writel(value, addr)						REG32(addr) = value        			//module_init(gmac_init_module);//module_exit(gmac_cleanup_module);void gmac_set_phy_status(void){    unsigned int value;    unsigned int i = 0;    if (FLAG_SWITCH==1)    {        return; /* GMAC connects to a switch chip, not PHY */    }            //    mii_write(PHY_ADDR,0x04,0x61);#ifdef GEMINI_ASIC	mii_write(PHY_ADDR,0x04,0x05e1); 	mii_write(PHY_ADDR,0x09,0x0300);#else   	mii_write(PHY_ADDR,0x04,0x05e1); /* advertisement 100M full duplex, pause capable on */   	mii_write(PHY_ADDR,0x09,0x0000); /* advertisement no 1000M */#endif        mii_write(PHY_ADDR,0x00,0x1200);//    while (((value=mii_read(PHY_ADDR,0x01)) & 0x00000004)!=0x04)//    {//        i++;//        if (i > 3000)//        {//            break ;//        }//	hal_delay_us(1000);//    }//    if (i<3000)//    {//        diag_printf("Link Up (%04x)\n",value);//    }//    else//    {    //        diag_printf("Link Down \n");//    }    //    value = mii_read(PHY_ADDR,0x05);//    if ((value & 0x0040) == 0x0040)//    {//        full_duplex = 1;//    }//    else//    {//        full_duplex = 0;//    }  	full_duplex = 1;      }    void gmac_get_phy_status(void){    GMAC_STATUS_T   status, old_status;    unsigned int    reg_val;    	status.bits32 = old_status.bits32 = gmac_read_reg(GMAC_STATUS);	#ifdef GEMINI_ASIC	status.bits.phy_mode = 1;#else        status.bits.phy_mode = 0;#endif	/* read PHY status register */	reg_val = mii_read(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(PHY_ADDR,10);	    if ((reg_val & 0x0800) == 0x0800)	    {	    	status.bits.mii_rmii = 3;	        status.bits.duplex = 1;	        status.bits.speed = 2;	    }	    else if ((reg_val & 0x0400) == 0x0400)	    { 	    	status.bits.mii_rmii = 3;	        status.bits.duplex = 0;	        status.bits.speed = 2;	    }	    else	    {    	      reg_val = (mii_read(PHY_ADDR,0x05) & 0x05E0) >> 5;	      status.bits.mii_rmii = 2;	      if ((reg_val & 0x08)==0x08) /* 100M full duplex */	        {	                status.bits.mii_rmii = 2;  /* RGMII 10/100Mbps mode */	                status.bits.duplex = 1;	                status.bits.speed = 1;	        }	        else if ((reg_val & 0x04)==0x04) /* 100M half duplex */	        {	                status.bits.mii_rmii = 2;  /* RGMII 10/100Mbps mode */	                status.bits.duplex = 0;	                status.bits.speed = 1;	        }	        else if ((reg_val & 0x02)==0x02) /* 10M full duplex */	        {	                status.bits.mii_rmii = 2;  /* RGMII 10/100Mbps mode */	                status.bits.duplex = 1;	                status.bits.speed = 0;	        }	        else if ((reg_val & 0x01)==0x01) /* 10M half duplex */	        {	                status.bits.mii_rmii = 2;  /* RGMII 10/100Mbps mode */	                status.bits.duplex = 0;	                status.bits.speed = 0;	        }	  }	    status.bits.link = 1; /* link up */	}	else	{	    status.bits.link = 0; /* link down */	}		if (status.bits32 != old_status.bits32)     	gmac_write_reg(GMAC_STATUS, status.bits32, 0x0000007f);}    /******************************************************************************//*           define GPIO module base address                                  *//******************************************************************************/#define GPIO_BASE_ADDR      SL2312_GPIO_BASE/* define GPIO pin for MDC/MDIO */#ifndef GEMINI_ASIC#define H_MDC_PIN           3#define H_MDIO_PIN          2#define G_MDC_PIN           0#define G_MDIO_PIN          1#else#define H_MDC_PIN           22#define H_MDIO_PIN          21#define G_MDC_PIN           22#define G_MDIO_PIN          21#endif//#define readl(addr)         (*addr)//#define writel(val,addr)    (*addr = val)// For PHY test definition!!#define LPC_EECK		    0x02#define LPC_EDIO		    0x04#define LPC_GPIO_SET		3#define LPC_BASE_ADDR		SL2312_LPC_IO_BASE #define inb_gpio(x)		    inb(LPC_BASE_ADDR + IT8712_GPIO_BASE + x)#define outb_gpio(x, y)		outb(y, LPC_BASE_ADDR + IT8712_GPIO_BASE + x)enum GPIO_REG{    GPIO_DATA_OUT   = 0x00,    GPIO_DATA_IN    = 0x04,    GPIO_PIN_DIR    = 0x08,    GPIO_BY_PASS    = 0x0c,    GPIO_DATA_SET   = 0x10,    GPIO_DATA_CLEAR = 0x14};static unsigned int GPIO_MDC = 0;static unsigned int GPIO_MDIO = 0;static unsigned int GPIO_MDC_PIN = 0;static unsigned int GPIO_MDIO_PIN = 0;/***********************//*    MDC : GPIO[31]   *//*    MDIO: GPIO[22]   *//***********************/      /**************************************************** All the commands should have the frame structure:*<PRE><ST><OP><PHYAD><REGAD><TA><DATA><IDLE>****************************************************//****************************************************************** Inject a bit to NWay register through CSR9_MDC,MDIO*******************************************************************/void mii_serial_write(char bit_MDO) // write data into mii PHY{#if 0 //LPC_IT8712 //CONFIG_SL2312_LPC_IT8712    	unsigned char iomode,status;		iomode = LPCGetConfig(LDN_GPIO, 0xc8 + LPC_GPIO_SET);	iomode |= (LPC_EECK|LPC_EDIO) ;				// Set EECK,EDIO,EECS output	LPCSetConfig(LDN_GPIO, 0xc8 + LPC_GPIO_SET, iomode);		if(bit_MDO)	{		status = inb_gpio( LPC_GPIO_SET);		status |= LPC_EDIO ;		//EDIO high		outb_gpio(LPC_GPIO_SET, status);		}	else	{		status = inb_gpio( LPC_GPIO_SET);		status &= ~(LPC_EDIO) ;		//EDIO low		outb_gpio(LPC_GPIO_SET, status);	}		status |= LPC_EECK ;		//EECK high	outb_gpio(LPC_GPIO_SET, status);		status &= ~(LPC_EECK) ;		//EECK low	outb_gpio(LPC_GPIO_SET, status);		#else    unsigned int *addr;    unsigned int value;    addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_PIN_DIR);    value = readl(addr) | GPIO_MDC | GPIO_MDIO; /* set MDC/MDIO Pin to output */    writel(value,addr);    if(bit_MDO)    {        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_SET);        writel(GPIO_MDIO,addr); /* set MDIO to 1 */        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_SET);        writel(GPIO_MDC,addr); /* set MDC to 1 */        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_CLEAR);        writel(GPIO_MDC,addr); /* set MDC to 0 */                        }    else    {        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_CLEAR);        writel(GPIO_MDIO,addr); /* set MDIO to 0 */        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_SET);        writel(GPIO_MDC,addr); /* set MDC to 1 */        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_CLEAR);        writel(GPIO_MDC,addr); /* set MDC to 0 */                        }   	#endif    }/*********************************************************************** read a bit from NWay register through CSR9_MDC,MDIO***********************************************************************/unsigned int mii_serial_read(void) // read data from mii PHY{#if 0 //LPC_IT8712 //CONFIG_SL2312_LPC_IT8712     	unsigned char iomode,status;	unsigned int value ;		iomode = LPCGetConfig(LDN_GPIO, 0xc8 + LPC_GPIO_SET);	iomode &= ~(LPC_EDIO) ;		// Set EDIO input	iomode |= (LPC_EECK) ;		// Set EECK,EECS output	LPCSetConfig(LDN_GPIO, 0xc8 + LPC_GPIO_SET, iomode);		status = inb_gpio( LPC_GPIO_SET);	status |= LPC_EECK ;		//EECK high	outb_gpio(LPC_GPIO_SET, status);			status &= ~(LPC_EECK) ;		//EECK low	outb_gpio(LPC_GPIO_SET, status);		value = inb_gpio( LPC_GPIO_SET);		value = value>>2 ;	value &= 0x01;			return value ;	#else    unsigned int *addr;    unsigned int value;        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_PIN_DIR);    value = readl(addr) & ~GPIO_MDIO; //0xffbfffff;   /* set MDC to output and MDIO to input */    writel(value,addr);        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_SET);    writel(GPIO_MDC,addr); /* set MDC to 1 */    addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_CLEAR);    writel(GPIO_MDC,addr); /* set MDC to 0 */                        addr = (unsigned int *)(GPIO_BASE_ADDR + GPIO_DATA_IN);    value = readl(addr);    value = (value & (1<<GPIO_MDIO_PIN)) >> GPIO_MDIO_PIN;    return(value);    #endif    }/**************************************** preamble + ST***************************************/void mii_pre_st(void){    unsigned char i;    for(i=0;i<32;i++) // PREAMBLE        mii_serial_write(1);    mii_serial_write(0); // ST    mii_serial_write(1);}/******************************************* Read MII register* phyad -> physical address* regad -> register address***************************************** */unsigned int mii_read(unsigned char phyad,unsigned char regad){    unsigned int i,value;    unsigned int bit;    if (phyad == GPHY_ADDR)    {        GPIO_MDC_PIN = G_MDC_PIN;   /* assigned MDC pin for giga PHY */        GPIO_MDIO_PIN = G_MDIO_PIN; /* assigned MDIO pin for giga PHY */    }    else    {            GPIO_MDC_PIN = H_MDC_PIN;   /* assigned MDC pin for 10/100 PHY */        GPIO_MDIO_PIN = H_MDIO_PIN; /* assigned MDIO pin for 10/100 PHY */    }    GPIO_MDC = (1<<GPIO_MDC_PIN);       GPIO_MDIO = (1<<GPIO_MDIO_PIN);                         mii_pre_st(); // PRE+ST    mii_serial_write(1); // OP    mii_serial_write(0);

⌨️ 快捷键说明

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