[U-Boot] [PATCH v2 1/3] davinci: emac: add new features to autonegotiate for EMAC

manjunath.hadli at ti.com manjunath.hadli at ti.com
Wed Oct 12 15:27:59 CEST 2011


From: Manjunath Hadli <manjunath.hadli at ti.com>

add more features like DUPLEX, 100MB link speed etc to auto negotiate
in EMAC driver. EMAC controller autonegotiates for these features with
PHYs which are on the board.

Tested-by: Laurence Withers <lwithers at guralp.com>
Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj at ti.com>
Signed-off-by: Manjunath Hadli <manjunath.hadli at ti.com>
---
 drivers/net/davinci_emac.c |   38 +++++++++++++++++++++----
 include/miiphy.h           |   67 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index a8905b8..4f492ad 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -279,20 +279,46 @@ static int gen_get_link_speed(int phy_addr)
 static int gen_auto_negotiate(int phy_addr)
 {
 	u_int16_t	tmp;
+	u_int16_t	val;
+	unsigned long	cntr = 0;
 
-	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+	if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
+		return 0;
+
+	val = tmp | PHY_BMCR_DPLX | PHY_BMCR_AUTON |
+						PHY_BMCR_100MB;
+	davinci_eth_phy_write(phy_addr, PHY_BMCR, val);
+
+	if (!davinci_eth_phy_read(phy_addr, PHY_ANAR, &val))
+		return 0;
+
+	val |= (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
+							PHY_ANLPAR_10);
+	davinci_eth_phy_write(phy_addr, PHY_ANAR, val);
+
+	if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
 		return(0);
 
 	/* Restart Auto_negotiation  */
-	tmp |= BMCR_ANENABLE;
-	davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
+	tmp |= PHY_BMCR_RST_NEG;
+	davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp);
 
 	/*check AutoNegotiate complete */
-	udelay (10000);
-	if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+	do {
+		udelay(40000);
+		if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
+			return 0;
+
+		if (tmp & PHY_BMSR_AUTN_COMP)
+			break;
+
+		cntr++;
+	} while (cntr < 200);
+
+	if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
 		return(0);
 
-	if (!(tmp & BMSR_ANEGCOMPLETE))
+	if (!(tmp & PHY_BMSR_AUTN_COMP))
 		return(0);
 
 	return(gen_get_link_speed(phy_addr));
diff --git a/include/miiphy.h b/include/miiphy.h
index 7e70cf8..a9be741 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -118,7 +118,72 @@ int bb_miiphy_write(const char *devname, unsigned char addr,
 #define FULL			44
 
 /* phy register offsets */
-#define MII_MIPSCR		0x11
+#define PHY_BMCR		0x00
+#define PHY_BMSR		0x01
+#define PHY_PHYIDR1		0x02
+#define PHY_PHYIDR2		0x03
+#define PHY_ANAR		0x04
+#define PHY_ANLPAR		0x05
+#define PHY_ANER		0x06
+#define PHY_ANNPTR		0x07
+#define PHY_ANLPNP		0x08
+#define PHY_1000BTCR		0x09
+#define PHY_1000BTSR		0x0A
+#define PHY_EXSR		0x0F
+#define PHY_PHYSTS		0x10
+#define PHY_MIPSCR		0x11
+#define PHY_MIPGSR		0x12
+#define PHY_DCR			0x13
+#define PHY_FCSCR		0x14
+#define PHY_RECR		0x15
+#define PHY_PCSR		0x16
+#define PHY_LBR			0x17
+#define PHY_10BTSCR		0x18
+#define PHY_PHYCTRL		0x19
+
+/* PHY BMCR */
+#define PHY_BMCR_RESET		0x8000
+#define PHY_BMCR_LOOP		0x4000
+#define PHY_BMCR_100MB		0x2000
+#define PHY_BMCR_AUTON		0x1000
+#define PHY_BMCR_POWD		0x0800
+#define PHY_BMCR_ISO		0x0400
+#define PHY_BMCR_RST_NEG	0x0200
+#define PHY_BMCR_DPLX		0x0100
+#define PHY_BMCR_COL_TST	0x0080
+
+#define PHY_BMCR_SPEED_MASK	0x2040
+#define PHY_BMCR_1000_MBPS	0x0040
+#define PHY_BMCR_100_MBPS	0x2000
+#define PHY_BMCR_10_MBPS	0x0000
+
+/* phy BMSR */
+#define PHY_BMSR_100T4		0x8000
+#define PHY_BMSR_100TXF		0x4000
+#define PHY_BMSR_100TXH		0x2000
+#define PHY_BMSR_10TF		0x1000
+#define PHY_BMSR_10TH		0x0800
+#define PHY_BMSR_EXT_STAT	0x0100
+#define PHY_BMSR_PRE_SUP	0x0040
+#define PHY_BMSR_AUTN_COMP	0x0020
+#define PHY_BMSR_RF		0x0010
+#define PHY_BMSR_AUTN_ABLE	0x0008
+#define PHY_BMSR_LS		0x0004
+#define PHY_BMSR_JD		0x0002
+#define PHY_BMSR_EXT		0x0001
+
+/*phy ANLPAR */
+#define PHY_ANLPAR_NP		0x8000
+#define PHY_ANLPAR_ACK		0x4000
+#define PHY_ANLPAR_RF		0x2000
+#define PHY_ANLPAR_ASYMP	0x0800
+#define PHY_ANLPAR_PAUSE	0x0400
+#define PHY_ANLPAR_T4		0x0200
+#define PHY_ANLPAR_TXFD		0x0100
+#define PHY_ANLPAR_TX		0x0080
+#define PHY_ANLPAR_10FD		0x0040
+#define PHY_ANLPAR_10		0x0020
+#define PHY_ANLPAR_100		0x0380	/* we can run at 100 */
 
 /* MII_LPA */
 #define PHY_ANLPAR_PSB_802_3	0x0001
-- 
1.6.2.4



More information about the U-Boot mailing list