]> git.sur5r.net Git - u-boot/blobdiff - drivers/net/at91_emac.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[u-boot] / drivers / net / at91_emac.c
index fa72e2cabdf8e4e3a0a89c334eff42b6034e16f0..4e5685c0c32b83fae2a46be6e6c33c43e9f4eacb 100644 (file)
        Please decrease the CONFIG_SYS_RX_ETH_BUFFER value
 #endif
 
+#ifndef CONFIG_DRIVER_AT91EMAC_PHYADDR
+#define CONFIG_DRIVER_AT91EMAC_PHYADDR 0
+#endif
+
 /* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
 #if (AT91C_MASTER_CLOCK > 80000000)
        #define HCLK_DIV        AT91_EMAC_CFG_MCLK_64
@@ -123,13 +127,19 @@ void at91emac_DisableMDIO(at91_emac_t *at91mac)
 int  at91emac_read(at91_emac_t *at91mac, unsigned char addr,
                unsigned char reg, unsigned short *value)
 {
+       unsigned long netstat;
        at91emac_EnableMDIO(at91mac);
 
        writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_R |
                AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
                AT91_EMAC_MAN_PHYA(addr),
                &at91mac->man);
-       udelay(10000);
+
+       do {
+               netstat = readl(&at91mac->sr);
+               DEBUG_AT91PHY("poll SR %08lx\n", netstat);
+       } while (!(netstat & AT91_EMAC_SR_IDLE));
+
        *value = readl(&at91mac->man) & AT91_EMAC_MAN_DATA_MASK;
 
        at91emac_DisableMDIO(at91mac);
@@ -142,6 +152,7 @@ int  at91emac_read(at91_emac_t *at91mac, unsigned char addr,
 int  at91emac_write(at91_emac_t *at91mac, unsigned char addr,
                unsigned char reg, unsigned short value)
 {
+       unsigned long netstat;
        DEBUG_AT91PHY("AT91PHY write %x REG(%d)=%x\n", at91mac, reg, &value)
 
        at91emac_EnableMDIO(at91mac);
@@ -150,15 +161,20 @@ int  at91emac_write(at91_emac_t *at91mac, unsigned char addr,
                AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
                AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK),
                &at91mac->man);
-       udelay(10000);
+
+       do {
+               netstat = readl(&at91mac->sr);
+               DEBUG_AT91PHY("poll SR %08lx\n", netstat);
+       } while (!(netstat & AT91_EMAC_SR_IDLE));
 
        at91emac_DisableMDIO(at91mac);
+
        return 0;
 }
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 
-at91_emac_t *get_emacbase_by_name(char *devname)
+at91_emac_t *get_emacbase_by_name(const char *devname)
 {
        struct eth_device *netdev;
 
@@ -166,7 +182,7 @@ at91_emac_t *get_emacbase_by_name(char *devname)
        return (at91_emac_t *) netdev->iobase;
 }
 
-int  at91emac_mii_read(char *devname, unsigned char addr,
+int  at91emac_mii_read(const char *devname, unsigned char addr,
                unsigned char reg, unsigned short *value)
 {
        at91_emac_t *emac;
@@ -177,7 +193,7 @@ int  at91emac_mii_read(char *devname, unsigned char addr,
 }
 
 
-int  at91emac_mii_write(char *devname, unsigned char addr,
+int  at91emac_mii_write(const char *devname, unsigned char addr,
                unsigned char reg, unsigned short value)
 {
        at91_emac_t *emac;
@@ -198,12 +214,15 @@ static int at91emac_phy_reset(struct eth_device *netdev)
        emac = (at91_emac_t *) netdev->iobase;
 
        adv = ADVERTISE_CSMA | ADVERTISE_ALL;
-       at91emac_write(emac, 0, MII_ADVERTISE, adv);
+       at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+               MII_ADVERTISE, adv);
        VERBOSEP("%s: Starting autonegotiation...\n", netdev->name);
-       at91emac_write(emac, 0, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
+       at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMCR,
+               (BMCR_ANENABLE | BMCR_ANRESTART));
 
-       for (i = 0; i < 100000 / 100; i++) {
-               at91emac_read(emac, 0, MII_BMSR, &status);
+       for (i = 0; i < 30000; i++) {
+               at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+                       MII_BMSR, &status);
                if (status & BMSR_ANEGCOMPLETE)
                        break;
                udelay(100);
@@ -214,7 +233,7 @@ static int at91emac_phy_reset(struct eth_device *netdev)
        } else {
                printf("%s: Autonegotiation timed out (status=0x%04x)\n",
                       netdev->name, status);
-               return 1;
+               return -1;
        }
        return 0;
 }
@@ -229,21 +248,24 @@ static int at91emac_phy_init(struct eth_device *netdev)
        emac = (at91_emac_t *) netdev->iobase;
 
        /* Check if the PHY is up to snuff... */
-       at91emac_read(emac, 0, MII_PHYSID1, &phy_id);
+       at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+               MII_PHYSID1, &phy_id);
        if (phy_id == 0xffff) {
                printf("%s: No PHY present\n", netdev->name);
-               return 1;
+               return -1;
        }
 
-       at91emac_read(emac, 0, MII_BMSR, &status);
+       at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+               MII_BMSR, &status);
 
        if (!(status & BMSR_LSTATUS)) {
                /* Try to re-negotiate if we don't have link already. */
                if (at91emac_phy_reset(netdev))
-                       return 2;
+                       return -2;
 
                for (i = 0; i < 100000 / 100; i++) {
-                       at91emac_read(emac, 0, MII_BMSR, &status);
+                       at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+                               MII_BMSR, &status);
                        if (status & BMSR_LSTATUS)
                                break;
                        udelay(100);
@@ -251,10 +273,12 @@ static int at91emac_phy_init(struct eth_device *netdev)
        }
        if (!(status & BMSR_LSTATUS)) {
                VERBOSEP("%s: link down\n", netdev->name);
-               return 3;
+               return -3;
        } else {
-               at91emac_read(emac, 0, MII_ADVERTISE, &adv);
-               at91emac_read(emac, 0, MII_LPA, &lpa);
+               at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+                       MII_ADVERTISE, &adv);
+               at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+                       MII_LPA, &lpa);
                media = mii_nway_result(lpa & adv);
                speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
                         ? 1 : 0);
@@ -271,10 +295,10 @@ int at91emac_UpdateLinkSpeed(at91_emac_t *emac)
 {
        unsigned short stat1;
 
-       at91emac_read(emac, 0, MII_BMSR, &stat1);
+       at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &stat1);
 
        if (!(stat1 & BMSR_LSTATUS))    /* link status up? */
-               return 1;
+               return -1;
 
        if (stat1 & BMSR_100FULL) {
                /*set Emac for 100BaseTX and Full Duplex  */
@@ -309,7 +333,7 @@ int at91emac_UpdateLinkSpeed(at91_emac_t *emac)
                        &emac->cfg);
                return 0;
        }
-       return 1;
+       return 0;
 }
 
 static int at91emac_init(struct eth_device *netdev, bd_t *bd)
@@ -364,7 +388,7 @@ static int at91emac_init(struct eth_device *netdev, bd_t *bd)
        value = AT91_EMAC_CFG_CAF |     AT91_EMAC_CFG_NBC |
                HCLK_DIV;
 #ifdef CONFIG_RMII
-       value |= AT91C_EMAC_RMII;
+       value |= AT91_EMAC_CFG_RMII;
 #endif
        writel(value, &emac->cfg);
 
@@ -375,7 +399,7 @@ static int at91emac_init(struct eth_device *netdev, bd_t *bd)
                at91emac_UpdateLinkSpeed(emac);
                return 0;
        }
-       return 1;
+       return -1;
 }
 
 static void at91emac_halt(struct eth_device *netdev)
@@ -477,22 +501,18 @@ int at91emac_register(bd_t *bis, unsigned long iobase)
                iobase = AT91_EMAC_BASE;
        emac = malloc(sizeof(*emac)+512);
        if (emac == NULL)
-               return 1;
+               return -1;
        dev = malloc(sizeof(*dev));
        if (dev == NULL) {
                free(emac);
-               return 1;
+               return -1;
        }
        /* alignment as per Errata (64 bytes) is insufficient! */
        emacfix = (emac_device *) (((unsigned long) emac + 0x1ff) & 0xFFFFFE00);
        memset(emacfix, 0, sizeof(emac_device));
 
        memset(dev, 0, sizeof(*dev));
-#ifndef CONFIG_RMII
-       sprintf(dev->name, "AT91 EMAC");
-#else
-       sprintf(dev->name, "AT91 EMAC RMII");
-#endif
+       sprintf(dev->name, "emac");
        dev->iobase = iobase;
        dev->priv = emacfix;
        dev->init = at91emac_init;