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
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);
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");
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;
else /* 10Mbps */
link_speed = 10;
- /* MAC Setup */
+ /*************************** MAC Setup ***************************/
tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress,
XEMACPSS_NWCFG_OFFSET);
if (link_speed == 10)
XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
XEMACPSS_NWCFG_OFFSET, tmp);
- /* GEM0_CLK Setup */
+ /************************* GEM0_CLK Setup *************************/
/* SLCR unlock */
Out32(0xF8000008, 0xDF0D);
/* 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;
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);
+
+}
+