davinci: emac: add new features to autonegotiate for EMAC
authorManjunath Hadli <manjunath.hadli@ti.com>
Thu, 13 Oct 2011 03:40:53 +0000 (03:40 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 27 Oct 2011 19:56:36 +0000 (21:56 +0200)
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.

Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
drivers/net/davinci_emac.c

index a8905b88f19fb958d0d5a18e6c715439c69456e1..52617a7fb74fdd1fce54bc433b80326c4131f088 100644 (file)
@@ -279,16 +279,42 @@ 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))
+               return 0;
+
+       val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE |
+                                               BMCR_SPEED100;
+       davinci_eth_phy_write(phy_addr, MII_BMCR, val);
+
+       if (!davinci_eth_phy_read(phy_addr, MII_ADVERTISE, &val))
+               return 0;
+
+       val |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL |
+                                                       ADVERTISE_10HALF);
+       davinci_eth_phy_write(phy_addr, MII_ADVERTISE, val);
 
        if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
                return(0);
 
        /* Restart Auto_negotiation  */
-       tmp |= BMCR_ANENABLE;
+       tmp |= BMCR_ANRESTART;
        davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
 
        /*check AutoNegotiate complete */
-       udelay (10000);
+       do {
+               udelay(40000);
+               if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+                       return 0;
+
+               if (tmp & BMSR_ANEGCOMPLETE)
+                       break;
+
+               cntr++;
+       } while (cntr < 200);
+
        if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
                return(0);