📄 lepus_gmac_phy.c
字号:
{ if(status.bits.mii_rmii == 2) status.bits.mii_rmii = 3; status.bits.duplex = 1; status.bits.speed = 2; } else if ((reg_val & 0x0400) == 0x0400) { if(status.bits.mii_rmii == 2) status.bits.mii_rmii = 3; status.bits.duplex = 0; status.bits.speed = 2; } else { reg_val = (mii_read(tp->phy_addr,0x05) & 0x05E0) >> 5; if(status.bits.mii_rmii == 3) status.bits.mii_rmii = 2; if ((reg_val & 0x08)==0x08) /* 100M full duplex */ { status.bits.duplex = 1; status.bits.speed = 1; } else if ((reg_val & 0x04)==0x04) /* 100M half duplex */ { status.bits.duplex = 0; status.bits.speed = 1; } else if ((reg_val & 0x02)==0x02) /* 10M full duplex */ { status.bits.duplex = 1; status.bits.speed = 0; } else if ((reg_val & 0x01)==0x01) /* 10M half duplex */ { status.bits.duplex = 0; status.bits.speed = 0; } } status.bits.link = LINK_UP; /* link up */ if ((reg_val & 0x20)==0x20) { if (tp->flow_control_enable == 0) { config0.bits32 = 0; config0_mask.bits32 = 0; config0.bits.tx_fc_en = 1; /* enable tx flow control */ config0.bits.rx_fc_en = 1; /* enable rx flow control */ config0_mask.bits.tx_fc_en = 1; config0_mask.bits.rx_fc_en = 1; gmac_write_reg(tp->base_addr, GMAC_CONFIG0,config0.bits32,config0_mask.bits32); // printf("Flow Control Enable. \n"); } tp->flow_control_enable = 1; } else { if (tp->flow_control_enable == 1) { config0.bits32 = 0; config0_mask.bits32 = 0; config0.bits.tx_fc_en = 0; /* disable tx flow control */ config0.bits.rx_fc_en = 0; /* disable rx flow control */ config0_mask.bits.tx_fc_en = 1; config0_mask.bits.rx_fc_en = 1; gmac_write_reg(tp->base_addr, GMAC_CONFIG0,config0.bits32,config0_mask.bits32); // printf("Flow Control Disable. \n"); } tp->flow_control_enable = 0; } if (tp->pre_phy_status == LINK_DOWN) { toe_gmac_enable_tx_rx(); tp->pre_phy_status = LINK_UP; // netif_wake_queue(dev); // set_bit(__LINK_STATE_START, &dev->state); } } else { status.bits.link = LINK_DOWN; /* link down */ if (tp->pre_phy_status == LINK_UP) { toe_gmac_disable_tx_rx(); tp->pre_phy_status = LINK_DOWN; // netif_stop_queue(dev); // clear_bit(__LINK_STATE_START, &dev->state); } } tp->full_duplex_status = status.bits.duplex; tp->speed_status = status.bits.speed; if (!tp->auto_nego_cfg) { status.bits.duplex = tp->full_duplex_cfg; status.bits.speed = tp->speed_cfg; } if (status.bits32 != old_status.bits32) gmac_write_reg(tp->base_addr, GMAC_STATUS, status.bits32, 0x0000007f); }}/***************************************//* define GPIO module base address *//***************************************/#define GPIO_BASE_ADDR (IO_ADDRESS(SL2312_GPIO_BASE))/* define GPIO pin for MDC/MDIO */#ifdef LEPUS_ASIC#define H_MDC_PIN 22#define H_MDIO_PIN 21#define G_MDC_PIN 22#define G_MDIO_PIN 21#else#define H_MDC_PIN 3#define H_MDIO_PIN 2#define G_MDC_PIN 0#define G_MDIO_PIN 1#endif//#define GPIO_MDC 0x80000000//#define GPIO_MDIO 0x00400000static 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;// For PHY test definition!!#define LPC_EECK 0x02#define LPC_EDIO 0x04#define LPC_GPIO_SET 3#define LPC_BASE_ADDR IO_ADDRESS(IT8712_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,};/***********************//* 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{#ifdef 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 = 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 = (GPIO_BASE_ADDR + GPIO_DATA_SET); writel(GPIO_MDIO,addr); /* set MDIO to 1 */ addr = (GPIO_BASE_ADDR + GPIO_DATA_SET); writel(GPIO_MDC,addr); /* set MDC to 1 */ addr = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_MDC,addr); /* set MDC to 0 */ } else { addr = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_MDIO,addr); /* set MDIO to 0 */ addr = (GPIO_BASE_ADDR + GPIO_DATA_SET); writel(GPIO_MDC,addr); /* set MDC to 1 */ addr = (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{#ifdef 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); for (i=0;i<5;i++) { // PHYAD bit= ((phyad>>(4-i)) & 0x01) ? 1 :0 ; mii_serial_write(bit); } for (i=0;i<5;i++) { // REGAD bit= ((regad>>(4-i)) & 0x01) ? 1 :0 ; mii_serial_write(bit); } mii_serial_read(); // TA_Z// if((bit=mii_serial_read()) !=0 ) // TA_0// {// return(0);// } value=0; for (i=0;i<16;i++) { // READ DATA bit=mii_serial_read(); value += (bit<<(15-i)) ; } mii_serial_write(0); // dumy clock mii_serial_write(0); // dumy clock //printf("%s: phy_addr=0x%x reg_addr=0x%x value=0x%x \n",__func__,phyad,regad,value); return(value);}/******************************************* Write MII register* phyad -> physical address* regad -> register address* value -> value to be write***************************************** */void mii_write(unsigned char phyad,unsigned char regad,unsigned int value){ unsigned int i; char bit; printf("%s: phy_addr=0x%x reg_addr=0x%x value=0x%x \n",__func__,phyad,regad,value); 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(0); // OP mii_serial_write(1); for (i=0;i<5;i++) { // PHYAD bit= ((phyad>>(4-i)) & 0x01) ? 1 :0 ; mii_serial_write(bit); } for (i=0;i<5;i++) { // REGAD bit= ((regad>>(4-i)) & 0x01) ? 1 :0 ; mii_serial_write(bit); } mii_serial_write(1); // TA_1 mii_serial_write(0); // TA_0 for (i=0;i<16;i++) { // OUT DATA bit= ((value>>(15-i)) & 0x01) ? 1 : 0 ; mii_serial_write(bit); } mii_serial_write(0); // dumy clock mii_serial_write(0); // dumy clock}#endif // #ifdef MIDWAY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -