From 160b5efffee5fb182cc7370d45a00995f835d6ac Mon Sep 17 00:00:00 2001 From: Andrei Simion Date: Thu, 22 Dec 2011 15:04:24 -0800 Subject: [PATCH] Xilinx: ARM: Clean-up of ethernet code. MAC/PHY driver has been cleaned up and commented thoroughly. Uneeded code has been removed. --- board/xilinx/dfe/xgmac.c | 152 +++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 61 deletions(-) diff --git a/board/xilinx/dfe/xgmac.c b/board/xilinx/dfe/xgmac.c index ea73bda94d7..198ee03eed6 100644 --- a/board/xilinx/dfe/xgmac.c +++ b/board/xilinx/dfe/xgmac.c @@ -15,6 +15,8 @@ int Xgmac_make_rxbuff_mem(XEmacPss * EmacPssInstancePtr, void *rx_buf_start, int Xgmac_next_rx_buf(XEmacPss * EmacPssInstancePtr); int Xgmac_phy_mgmt_idle(XEmacPss * EmacPssInstancePtr); +void set_eth_advertise(XEmacPss * EmacPssInstancePtr, int link_speed); + /*************************** Constant Definitions ***************************/ #define EMACPSS_DEVICE_ID 0 @@ -181,31 +183,21 @@ int eth_init(bd_t * bis) XEMACPSS_TXQBASE_OFFSET, EmacPssInstancePtr->TxBdRing.BaseBdAddr); - /* MAC Setup */ /* - * Following is the setup for Network Configuration register. - * Bit 0: Set for 100 Mbps operation. - * Bit 1: Set for Full Duplex mode. - * Bit 4: Set to allow Copy all frames. - * Bit 10: Set for Gigabit. - * Bit 17: Set for FCS removal. - * Bits 20-18: Set with value binary 010 to divide pclk by 32 - * (pclk up to 80 MHz) + * Setup the ethernet. */ + printf("Trying to set up GEM link...\n"); + + /*************************** MAC Setup ***************************/ + tmp = (2 << 18); /* MDC clock division (32 for up to 80MHz) */ + tmp |= (1 << 17); /* set for FCS removal */ + tmp |= (1 << 10); /* enable gigabit */ + tmp |= (1 << 4); /* copy all frames */ + tmp |= (1 << 1); /* enable full duplex */ + XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress, - XEMACPSS_NWCFG_OFFSET, 0x000A0413); + XEMACPSS_NWCFG_OFFSET, tmp); - /* - * Following is the setup for DMA Configuration register. - * Bits 4-0: To set AHB fixed burst length for DMA data operations -> - * Set with binary 00100 to use INCR4 AHB bursts. - * Bits 9-8: Receiver packet buffer memory size -> - * Set with binary 11 to Use full configured addressable space (8 Kb) - * Bit 10 : Transmitter packet buffer memory size -> - * Set with binary 1 to Use full configured addressable space (4 Kb) - * Bits 23-16 : DMA receive buffer size in AHB system memory -> - * Set with binary 00011000 to use 1536 byte (1*max length frame/buffer). - */ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress, XEMACPSS_DMACR_OFFSET, 0x00180704); @@ -213,79 +205,70 @@ int eth_init(bd_t * bis) XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress, XEMACPSS_IDR_OFFSET, 0xFFFFFFFF); - /* - * Following is the setup for Network Control register. - * Bit 2: Set to enable Receive operation. - * Bit 3: Set to enable Transmitt operation. - * Bit 4: Set to enable MDIO operation. - */ + /* MDIO, Rx and Tx enable */ tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress, XEMACPSS_NWCTRL_OFFSET); - /*MDIO, Rx and Tx enable */ tmp |= XEMACPSS_NWCTRL_MDEN_MASK | XEMACPSS_NWCTRL_RXEN_MASK | XEMACPSS_NWCTRL_TXEN_MASK; XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress, XEMACPSS_NWCTRL_OFFSET, tmp); - /* PHY Setup */ - -#ifdef CONFIG_EP107 - /* "add delay to RGMII rx interface" */ - phy_wr(EmacPssInstancePtr, 20, 0xc93); -#else - phy_wr(EmacPssInstancePtr, 22, 2); /* page 2 */ - - /* rx clock transition when data stable */ - phy_wr(EmacPssInstancePtr, 21, 0x3030); + /*************************** PHY Setup ***************************/ phy_wr(EmacPssInstancePtr, 22, 0); /* page 0 */ -#endif - /* link speed advertisement for autonegotiation */ + /* Auto-negotiation advertisement register */ tmp = phy_rd(EmacPssInstancePtr, 4); - tmp |= 0xd80; /* enable 100Mbps */ - tmp |= 0x60; /* enable 10 Mbps */ + tmp |= (1 << 11); /* asymmetric pause */ + tmp |= (1 << 10); /* MAC pause implemented */ phy_wr(EmacPssInstancePtr, 4, tmp); - /* enable gigabit advertisement */ - tmp = phy_rd(EmacPssInstancePtr, 9); - tmp |= 0x0300; - phy_wr(EmacPssInstancePtr, 9, tmp); - /* Copper specific control register 1 */ - phy_wr(EmacPssInstancePtr, 22, 0); tmp = phy_rd(EmacPssInstancePtr, 16); tmp |= (7 << 12); /* max number of gigabit attempts */ tmp |= (1 << 11); /* enable downshift */ phy_wr(EmacPssInstancePtr, 16, tmp); - /* enable autonegotiation, set 100Mbps, full-duplex, restart aneg */ +#ifdef CONFIG_EP107 + /* "add delay to RGMII rx interface" */ + phy_wr(EmacPssInstancePtr, 20, 0xc93); +#else + phy_wr(EmacPssInstancePtr, 22, 2); /* page 2 */ + tmp = phy_rd(EmacPssInstancePtr, 21); + tmp |= (1 << 5); /* RGMII receive timing transition when data stable */ + tmp |= (1 << 4); /* RGMII transmit clock internally delayed */ + phy_wr(EmacPssInstancePtr, 21, tmp); + phy_wr(EmacPssInstancePtr, 22, 0); /* page 0 */ +#endif + + /* Control register */ tmp = phy_rd(EmacPssInstancePtr, 0); - phy_wr(EmacPssInstancePtr, 0, 0x3300 | (tmp & 0x1F)); + tmp |= (1 << 12); /* auto-negotiation enable */ + tmp |= (1 << 8); /* enable full duplex */ + phy_wr(EmacPssInstancePtr, 0, tmp); + /***** Try to establish a link at the highest speed possible *****/ + set_eth_advertise(EmacPssInstancePtr, 1000); phy_rst(EmacPssInstancePtr); - puts("\nWaiting for PHY to complete autonegotiation."); + /* Attempt auto-negotiation */ + puts("Waiting for PHY to complete auto-negotiation...\n"); tmp = 0; /* delay counter */ while (!(phy_rd(EmacPssInstancePtr, 1) & (1 << 5))) { udelay(10000); tmp++; if (tmp > 1000) { /* stalled if no link after 10 seconds */ - printf("***Error: Auto-negotiation stalled...\n"); + puts("***Error: Auto-negotiation stalled...\n"); return -1; } } - puts("\nPHY claims autonegotiation complete...\n"); - /* Check if the link is up */ - phy_wr(EmacPssInstancePtr, 22, 0); tmp = phy_rd(EmacPssInstancePtr, 17); if ( ((tmp >> 10) & 1) ) { /* Check for an auto-negotiation error */ - phy_wr(EmacPssInstancePtr, 22, 0); tmp = phy_rd(EmacPssInstancePtr, 19); if ( (tmp >> 15) & 1 ) { puts("***Error: Auto-negotiation error is present.\n"); @@ -296,8 +279,7 @@ int eth_init(bd_t * bis) return -1; } - /* Determine link speed */ - phy_wr(EmacPssInstancePtr, 22, 0); + /********************** Determine link speed **********************/ tmp = phy_rd(EmacPssInstancePtr, 17); if ( ((tmp >> 14) & 3) == 2) /* 1000Mbps */ link_speed = 1000; @@ -306,7 +288,7 @@ int eth_init(bd_t * bis) else /* 10Mbps */ link_speed = 10; - /* MAC Setup */ + /*************************** MAC Setup ***************************/ tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress, XEMACPSS_NWCFG_OFFSET); if (link_speed == 10) @@ -320,7 +302,7 @@ int eth_init(bd_t * bis) XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress, XEMACPSS_NWCFG_OFFSET, tmp); - /* GEM0_CLK Setup */ + /************************* GEM0_CLK Setup *************************/ /* SLCR unlock */ Out32(0xF8000008, 0xDF0D); @@ -338,7 +320,7 @@ int eth_init(bd_t * bis) /* SLCR lock */ Out32(0xF8000008, 0x767B); - printf("GEM link speed is %dMbps!\n", link_speed); + printf("Link is now at %dMbps!\n", link_speed); ethstate.initialized = 1; return 0; @@ -608,3 +590,51 @@ int Xgmac_next_rx_buf(XEmacPss * EmacPssInstancePtr) return 0; } + +void set_eth_advertise(XEmacPss * EmacPssInstancePtr, int link_speed) { + + int tmp; + + /* MAC setup */ + tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress, + XEMACPSS_NWCFG_OFFSET); + if (link_speed == 10) + tmp &= ~(1 << 0); /* enable 10Mbps */ + else if (link_speed == 100) + tmp |= (1 << 0); /* enable 100Mbps */ + XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress, + XEMACPSS_NWCFG_OFFSET, tmp); + + phy_wr(EmacPssInstancePtr, 22, 0); /* page 0 */ + + /* Auto-negotiation advertisement register */ + tmp = phy_rd(EmacPssInstancePtr, 4); + if (link_speed >= 100) { + tmp |= (1 << 8); /* advertise 100Mbps F */ + tmp |= (1 << 7); /* advertise 100Mbps H */ + } else { + tmp &= ~(1 << 8); /* advertise 100Mbps F */ + tmp &= ~(1 << 7); /* advertise 100Mbps H */ + } + if (link_speed >= 10) { + tmp |= (1 << 6); /* advertise 10Mbps F */ + tmp |= (1 << 5); /* advertise 10Mbps H */ + } else { + tmp &= ~(1 << 6); /* advertise 10Mbps F */ + tmp &= ~(1 << 5); /* advertise 10Mbps H */ + } + phy_wr(EmacPssInstancePtr, 4, tmp); + + /* 1000BASE-T control register */ + tmp = phy_rd(EmacPssInstancePtr, 9); + if (link_speed == 1000) { + tmp |= (1 << 9); /* advertise 1000Mbps F */ + tmp |= (1 << 8); /* advertise 1000Mbps H */ + } else { + tmp &= ~(1 << 9); /* advertise 1000Mbps F */ + tmp &= ~(1 << 8); /* advertise 1000Mbps H */ + } + phy_wr(EmacPssInstancePtr, 9, tmp); + +} + -- 2.47.3