X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Fat91_emac.c;h=64d4c56ac56ac3b996b3659a3c9b81e473f8ec14;hb=af2d3470bd9b61d5df3fd809562c26c540fbafca;hp=245da121b94d520e12eb562641c12945ae6aaa8c;hpb=9efac4a1eb99d9c5539aa6992025eeacab7980c6;p=karo-tx-uboot.git diff --git a/drivers/net/at91_emac.c b/drivers/net/at91_emac.c index 245da121b9..64d4c56ac5 100644 --- a/drivers/net/at91_emac.c +++ b/drivers/net/at91_emac.c @@ -5,40 +5,15 @@ * (C) Copyright 2003 * Author : Hamid Ikdoumi (Atmel) - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include #include -#ifndef CONFIG_AT91_LEGACY #include #include #include #include -#else -/* remove next 5 lines, if all RM9200 boards convert to at91 arch */ -#include -#include -#include -#include -#include -#endif #include #include #include @@ -69,21 +44,21 @@ #endif #ifdef ET_DEBUG -#define DEBUG_AT91EMAC(...) printf(__VA_ARGS__); +#define DEBUG_AT91EMAC 1 #else -#define DEBUG_AT91EMAC(...) +#define DEBUG_AT91EMAC 0 #endif #ifdef MII_DEBUG -#define DEBUG_AT91PHY(...) printf(__VA_ARGS__); +#define DEBUG_AT91PHY 1 #else -#define DEBUG_AT91PHY(...) +#define DEBUG_AT91PHY 0 #endif #ifndef CONFIG_DRIVER_AT91EMAC_QUIET -#define VERBOSEP(...) printf(__VA_ARGS__); +#define VERBOSEP 1 #else -#define VERBOSEP(...) +#define VERBOSEP 0 #endif #define RBF_ADDR 0xfffffffc @@ -93,7 +68,7 @@ #define RBF_MULTICAST (1<<30) #define RBF_UNICAST (1<<29) #define RBF_EXTERNAL (1<<28) -#define RBF_UNKOWN (1<<27) +#define RBF_UNKNOWN (1<<27) #define RBF_SIZE 0x07ff #define RBF_LOCAL4 (1<<26) #define RBF_LOCAL3 (1<<25) @@ -127,18 +102,25 @@ 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_cond(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); - DEBUG_AT91PHY("AT91PHY read %x REG(%d)=%x\n", at91mac, reg, *value) + debug_cond(DEBUG_AT91PHY, + "AT91PHY read %p REG(%d)=%x\n", at91mac, reg, *value); return 0; } @@ -146,7 +128,9 @@ 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) { - DEBUG_AT91PHY("AT91PHY write %x REG(%d)=%x\n", at91mac, reg, &value) + unsigned long netstat; + debug_cond(DEBUG_AT91PHY, + "AT91PHY write %p REG(%d)=%p\n", at91mac, reg, &value); at91emac_EnableMDIO(at91mac); @@ -154,15 +138,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_cond(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; @@ -170,7 +159,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; @@ -181,7 +170,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; @@ -204,11 +193,11 @@ static int at91emac_phy_reset(struct eth_device *netdev) adv = ADVERTISE_CSMA | ADVERTISE_ALL; at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_ADVERTISE, adv); - VERBOSEP("%s: Starting autonegotiation...\n", netdev->name); + debug_cond(VERBOSEP, "%s: Starting autonegotiation...\n", netdev->name); at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART)); - for (i = 0; i < 100000 / 100; i++) { + for (i = 0; i < 30000; i++) { at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &status); if (status & BMSR_ANEGCOMPLETE) @@ -217,11 +206,12 @@ static int at91emac_phy_reset(struct eth_device *netdev) } if (status & BMSR_ANEGCOMPLETE) { - VERBOSEP("%s: Autonegotiation complete\n", netdev->name); + debug_cond(VERBOSEP, + "%s: Autonegotiation complete\n", netdev->name); } else { printf("%s: Autonegotiation timed out (status=0x%04x)\n", netdev->name, status); - return 1; + return -1; } return 0; } @@ -240,7 +230,7 @@ static int at91emac_phy_init(struct eth_device *netdev) MII_PHYSID1, &phy_id); if (phy_id == 0xffff) { printf("%s: No PHY present\n", netdev->name); - return 1; + return -1; } at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, @@ -249,7 +239,7 @@ static int at91emac_phy_init(struct eth_device *netdev) 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, CONFIG_DRIVER_AT91EMAC_PHYADDR, @@ -260,8 +250,8 @@ static int at91emac_phy_init(struct eth_device *netdev) } } if (!(status & BMSR_LSTATUS)) { - VERBOSEP("%s: link down\n", netdev->name); - return 3; + debug_cond(VERBOSEP, "%s: link down\n", netdev->name); + return -3; } else { at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_ADVERTISE, &adv); @@ -271,7 +261,7 @@ static int at91emac_phy_init(struct eth_device *netdev) speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; - VERBOSEP("%s: link up, %sMbps %s-duplex\n", + debug_cond(VERBOSEP, "%s: link up, %sMbps %s-duplex\n", netdev->name, speed ? "100" : "10", duplex ? "full" : "half"); @@ -286,7 +276,7 @@ int at91emac_UpdateLinkSpeed(at91_emac_t *emac) 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 */ @@ -321,7 +311,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) @@ -330,34 +320,34 @@ static int at91emac_init(struct eth_device *netdev, bd_t *bd) u32 value; emac_device *dev; at91_emac_t *emac; - at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO; + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; emac = (at91_emac_t *) netdev->iobase; dev = (emac_device *) netdev->priv; /* PIO Disable Register */ - value = AT91_PMX_AA_EMDIO | AT91_PMX_AA_EMDC | - AT91_PMX_AA_ERXER | AT91_PMX_AA_ERX1 | - AT91_PMX_AA_ERX0 | AT91_PMX_AA_ECRS | - AT91_PMX_AA_ETX1 | AT91_PMX_AA_ETX0 | - AT91_PMX_AA_ETXEN | AT91_PMX_AA_EREFCK; + value = ATMEL_PMX_AA_EMDIO | ATMEL_PMX_AA_EMDC | + ATMEL_PMX_AA_ERXER | ATMEL_PMX_AA_ERX1 | + ATMEL_PMX_AA_ERX0 | ATMEL_PMX_AA_ECRS | + ATMEL_PMX_AA_ETX1 | ATMEL_PMX_AA_ETX0 | + ATMEL_PMX_AA_ETXEN | ATMEL_PMX_AA_EREFCK; writel(value, &pio->pioa.pdr); writel(value, &pio->pioa.asr); #ifdef CONFIG_RMII - value = AT91_PMX_BA_ERXCK; + value = ATMEL_PMX_BA_ERXCK; #else - value = AT91_PMX_BA_ERXCK | AT91_PMX_BA_ECOL | - AT91_PMX_BA_ERXDV | AT91_PMX_BA_ERX3 | - AT91_PMX_BA_ERX2 | AT91_PMX_BA_ETXER | - AT91_PMX_BA_ETX3 | AT91_PMX_BA_ETX2; + value = ATMEL_PMX_BA_ERXCK | ATMEL_PMX_BA_ECOL | + ATMEL_PMX_BA_ERXDV | ATMEL_PMX_BA_ERX3 | + ATMEL_PMX_BA_ERX2 | ATMEL_PMX_BA_ETXER | + ATMEL_PMX_BA_ETX3 | ATMEL_PMX_BA_ETX2; #endif writel(value, &pio->piob.pdr); writel(value, &pio->piob.bsr); - writel(1 << AT91_ID_EMAC, &pmc->pcer); + writel(1 << ATMEL_ID_EMAC, &pmc->pcer); writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl); /* Init Ethernet buffers */ @@ -387,7 +377,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) @@ -397,11 +387,10 @@ static void at91emac_halt(struct eth_device *netdev) emac = (at91_emac_t *) netdev->iobase; writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE), &emac->ctl); - DEBUG_AT91EMAC("halt MAC\n"); + debug_cond(DEBUG_AT91EMAC, "halt MAC\n"); } -static int at91emac_send(struct eth_device *netdev, volatile void *packet, - int length) +static int at91emac_send(struct eth_device *netdev, void *packet, int length) { at91_emac_t *emac; @@ -413,7 +402,7 @@ static int at91emac_send(struct eth_device *netdev, volatile void *packet, writel(AT91_EMAC_TCR_LEN(length), &emac->tcr); while (AT91_EMAC_TCR_LEN(readl(&emac->tcr))) ; - DEBUG_AT91EMAC("Send %d \n", length); + debug_cond(DEBUG_AT91EMAC, "Send %d\n", length); writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr); return 0; } @@ -433,7 +422,7 @@ static int at91emac_recv(struct eth_device *netdev) size = rbfp->size & RBF_SIZE; NetReceive(NetRxPackets[dev->rbindex], size); - DEBUG_AT91EMAC("Recv[%d]: %d bytes @ %x \n", + debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n", dev->rbindex, size, rbfp->addr); rbfp->addr &= ~RBF_OWNER; @@ -462,19 +451,20 @@ static int at91emac_recv(struct eth_device *netdev) static int at91emac_write_hwaddr(struct eth_device *netdev) { - emac_device *dev; at91_emac_t *emac; - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; emac = (at91_emac_t *) netdev->iobase; - dev = (emac_device *) netdev->priv; - writel(1 << AT91_ID_EMAC, &pmc->pcer); - DEBUG_AT91EMAC("init MAC-ADDR %x%x \n", - cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), - cpu_to_le32(*((u32 *)netdev->enetaddr))); - writel(cpu_to_le32(*((u32 *)netdev->enetaddr)), &emac->sa2l); - writel(cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), &emac->sa2h); - DEBUG_AT91EMAC("init MAC-ADDR %x%x \n", + writel(1 << ATMEL_ID_EMAC, &pmc->pcer); + debug_cond(DEBUG_AT91EMAC, + "init MAC-ADDR %02x:%02x:%02x:%02x:%02x:%02x\n", + netdev->enetaddr[5], netdev->enetaddr[4], netdev->enetaddr[3], + netdev->enetaddr[2], netdev->enetaddr[1], netdev->enetaddr[0]); + writel( (netdev->enetaddr[0] | netdev->enetaddr[1] << 8 | + netdev->enetaddr[2] << 16 | netdev->enetaddr[3] << 24), + &emac->sa2l); + writel((netdev->enetaddr[4] | netdev->enetaddr[5] << 8), &emac->sa2h); + debug_cond(DEBUG_AT91EMAC, "init MAC-ADDR %x%x\n", readl(&emac->sa2h), readl(&emac->sa2l)); return 0; } @@ -486,25 +476,21 @@ int at91emac_register(bd_t *bis, unsigned long iobase) struct eth_device *dev; if (iobase == 0) - iobase = AT91_EMAC_BASE; + iobase = ATMEL_BASE_EMAC; 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;