uboot/drivers/net/at91_emac.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2009 BuS Elektronik GmbH & Co. KG
   4 * Jens Scharsig (esw@bus-elektronik.de)
   5 *
   6 * (C) Copyright 2003
   7 * Author : Hamid Ikdoumi (Atmel)
   8 */
   9
  10#include <common.h>
  11#include <log.h>
  12#include <asm/io.h>
  13#include <asm/arch/hardware.h>
  14#include <asm/arch/at91_emac.h>
  15#include <asm/arch/clk.h>
  16#include <asm/arch/at91_pio.h>
  17#include <net.h>
  18#include <netdev.h>
  19#include <malloc.h>
  20#include <miiphy.h>
  21#include <linux/delay.h>
  22#include <linux/mii.h>
  23
  24#undef MII_DEBUG
  25#undef ET_DEBUG
  26
  27#if (CONFIG_SYS_RX_ETH_BUFFER > 1024)
  28#error AT91 EMAC supports max 1024 RX buffers. \
  29        Please decrease the CONFIG_SYS_RX_ETH_BUFFER value
  30#endif
  31
  32#ifndef CONFIG_DRIVER_AT91EMAC_PHYADDR
  33#define CONFIG_DRIVER_AT91EMAC_PHYADDR  0
  34#endif
  35
  36/* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
  37#if (AT91C_MASTER_CLOCK > 80000000)
  38        #define HCLK_DIV        AT91_EMAC_CFG_MCLK_64
  39#elif (AT91C_MASTER_CLOCK > 40000000)
  40        #define HCLK_DIV        AT91_EMAC_CFG_MCLK_32
  41#elif (AT91C_MASTER_CLOCK > 20000000)
  42        #define HCLK_DIV        AT91_EMAC_CFG_MCLK_16
  43#else
  44        #define HCLK_DIV        AT91_EMAC_CFG_MCLK_8
  45#endif
  46
  47#ifdef ET_DEBUG
  48#define DEBUG_AT91EMAC  1
  49#else
  50#define DEBUG_AT91EMAC  0
  51#endif
  52
  53#ifdef MII_DEBUG
  54#define DEBUG_AT91PHY   1
  55#else
  56#define DEBUG_AT91PHY   0
  57#endif
  58
  59#ifndef CONFIG_DRIVER_AT91EMAC_QUIET
  60#define VERBOSEP        1
  61#else
  62#define VERBOSEP        0
  63#endif
  64
  65#define RBF_ADDR      0xfffffffc
  66#define RBF_OWNER     (1<<0)
  67#define RBF_WRAP      (1<<1)
  68#define RBF_BROADCAST (1<<31)
  69#define RBF_MULTICAST (1<<30)
  70#define RBF_UNICAST   (1<<29)
  71#define RBF_EXTERNAL  (1<<28)
  72#define RBF_UNKNOWN   (1<<27)
  73#define RBF_SIZE      0x07ff
  74#define RBF_LOCAL4    (1<<26)
  75#define RBF_LOCAL3    (1<<25)
  76#define RBF_LOCAL2    (1<<24)
  77#define RBF_LOCAL1    (1<<23)
  78
  79#define RBF_FRAMEMAX CONFIG_SYS_RX_ETH_BUFFER
  80#define RBF_FRAMELEN 0x600
  81
  82typedef struct {
  83        unsigned long addr, size;
  84} rbf_t;
  85
  86typedef struct {
  87        rbf_t           rbfdt[RBF_FRAMEMAX];
  88        unsigned long   rbindex;
  89} emac_device;
  90
  91void at91emac_EnableMDIO(at91_emac_t *at91mac)
  92{
  93        /* Mac CTRL reg set for MDIO enable */
  94        writel(readl(&at91mac->ctl) | AT91_EMAC_CTL_MPE, &at91mac->ctl);
  95}
  96
  97void at91emac_DisableMDIO(at91_emac_t *at91mac)
  98{
  99        /* Mac CTRL reg set for MDIO disable */
 100        writel(readl(&at91mac->ctl) & ~AT91_EMAC_CTL_MPE, &at91mac->ctl);
 101}
 102
 103int  at91emac_read(at91_emac_t *at91mac, unsigned char addr,
 104                unsigned char reg, unsigned short *value)
 105{
 106        unsigned long netstat;
 107        at91emac_EnableMDIO(at91mac);
 108
 109        writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_R |
 110                AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
 111                AT91_EMAC_MAN_PHYA(addr),
 112                &at91mac->man);
 113
 114        do {
 115                netstat = readl(&at91mac->sr);
 116                debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat);
 117        } while (!(netstat & AT91_EMAC_SR_IDLE));
 118
 119        *value = readl(&at91mac->man) & AT91_EMAC_MAN_DATA_MASK;
 120
 121        at91emac_DisableMDIO(at91mac);
 122
 123        debug_cond(DEBUG_AT91PHY,
 124                "AT91PHY read %p REG(%d)=%x\n", at91mac, reg, *value);
 125
 126        return 0;
 127}
 128
 129int  at91emac_write(at91_emac_t *at91mac, unsigned char addr,
 130                unsigned char reg, unsigned short value)
 131{
 132        unsigned long netstat;
 133        debug_cond(DEBUG_AT91PHY,
 134                "AT91PHY write %p REG(%d)=%p\n", at91mac, reg, &value);
 135
 136        at91emac_EnableMDIO(at91mac);
 137
 138        writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_W |
 139                AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
 140                AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK),
 141                &at91mac->man);
 142
 143        do {
 144                netstat = readl(&at91mac->sr);
 145                debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat);
 146        } while (!(netstat & AT91_EMAC_SR_IDLE));
 147
 148        at91emac_DisableMDIO(at91mac);
 149
 150        return 0;
 151}
 152
 153#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 154
 155at91_emac_t *get_emacbase_by_name(const char *devname)
 156{
 157        struct eth_device *netdev;
 158
 159        netdev = eth_get_dev_by_name(devname);
 160        return (at91_emac_t *) netdev->iobase;
 161}
 162
 163int at91emac_mii_read(struct mii_dev *bus, int addr, int devad, int reg)
 164{
 165        unsigned short value = 0;
 166        at91_emac_t *emac;
 167
 168        emac = get_emacbase_by_name(bus->name);
 169        at91emac_read(emac , addr, reg, &value);
 170        return value;
 171}
 172
 173
 174int at91emac_mii_write(struct mii_dev *bus, int addr, int devad, int reg,
 175                       u16 value)
 176{
 177        at91_emac_t *emac;
 178
 179        emac = get_emacbase_by_name(bus->name);
 180        at91emac_write(emac, addr, reg, value);
 181        return 0;
 182}
 183
 184#endif
 185
 186static int at91emac_phy_reset(struct eth_device *netdev)
 187{
 188        int i;
 189        u16 status, adv;
 190        at91_emac_t *emac;
 191
 192        emac = (at91_emac_t *) netdev->iobase;
 193
 194        adv = ADVERTISE_CSMA | ADVERTISE_ALL;
 195        at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 196                MII_ADVERTISE, adv);
 197        debug_cond(VERBOSEP, "%s: Starting autonegotiation...\n", netdev->name);
 198        at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMCR,
 199                (BMCR_ANENABLE | BMCR_ANRESTART));
 200
 201        for (i = 0; i < 30000; i++) {
 202                at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 203                        MII_BMSR, &status);
 204                if (status & BMSR_ANEGCOMPLETE)
 205                        break;
 206                udelay(100);
 207        }
 208
 209        if (status & BMSR_ANEGCOMPLETE) {
 210                debug_cond(VERBOSEP,
 211                        "%s: Autonegotiation complete\n", netdev->name);
 212        } else {
 213                printf("%s: Autonegotiation timed out (status=0x%04x)\n",
 214                       netdev->name, status);
 215                return -1;
 216        }
 217        return 0;
 218}
 219
 220static int at91emac_phy_init(struct eth_device *netdev)
 221{
 222        u16 phy_id, status, adv, lpa;
 223        int media, speed, duplex;
 224        int i;
 225        at91_emac_t *emac;
 226
 227        emac = (at91_emac_t *) netdev->iobase;
 228
 229        /* Check if the PHY is up to snuff... */
 230        at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 231                MII_PHYSID1, &phy_id);
 232        if (phy_id == 0xffff) {
 233                printf("%s: No PHY present\n", netdev->name);
 234                return -1;
 235        }
 236
 237        at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 238                MII_BMSR, &status);
 239
 240        if (!(status & BMSR_LSTATUS)) {
 241                /* Try to re-negotiate if we don't have link already. */
 242                if (at91emac_phy_reset(netdev))
 243                        return -2;
 244
 245                for (i = 0; i < 100000 / 100; i++) {
 246                        at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 247                                MII_BMSR, &status);
 248                        if (status & BMSR_LSTATUS)
 249                                break;
 250                        udelay(100);
 251                }
 252        }
 253        if (!(status & BMSR_LSTATUS)) {
 254                debug_cond(VERBOSEP, "%s: link down\n", netdev->name);
 255                return -3;
 256        } else {
 257                at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 258                        MII_ADVERTISE, &adv);
 259                at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
 260                        MII_LPA, &lpa);
 261                media = mii_nway_result(lpa & adv);
 262                speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
 263                         ? 1 : 0);
 264                duplex = (media & ADVERTISE_FULL) ? 1 : 0;
 265                debug_cond(VERBOSEP, "%s: link up, %sMbps %s-duplex\n",
 266                       netdev->name,
 267                       speed ? "100" : "10",
 268                       duplex ? "full" : "half");
 269        }
 270        return 0;
 271}
 272
 273int at91emac_UpdateLinkSpeed(at91_emac_t *emac)
 274{
 275        unsigned short stat1;
 276
 277        at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &stat1);
 278
 279        if (!(stat1 & BMSR_LSTATUS))    /* link status up? */
 280                return -1;
 281
 282        if (stat1 & BMSR_100FULL) {
 283                /*set Emac for 100BaseTX and Full Duplex  */
 284                writel(readl(&emac->cfg) |
 285                        AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD,
 286                        &emac->cfg);
 287                return 0;
 288        }
 289
 290        if (stat1 & BMSR_10FULL) {
 291                /*set MII for 10BaseT and Full Duplex  */
 292                writel((readl(&emac->cfg) &
 293                        ~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
 294                        ) | AT91_EMAC_CFG_FD,
 295                        &emac->cfg);
 296                return 0;
 297        }
 298
 299        if (stat1 & BMSR_100HALF) {
 300                /*set MII for 100BaseTX and Half Duplex  */
 301                writel((readl(&emac->cfg) &
 302                        ~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
 303                        ) | AT91_EMAC_CFG_SPD,
 304                        &emac->cfg);
 305                return 0;
 306        }
 307
 308        if (stat1 & BMSR_10HALF) {
 309                /*set MII for 10BaseT and Half Duplex  */
 310                writel((readl(&emac->cfg) &
 311                        ~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)),
 312                        &emac->cfg);
 313                return 0;
 314        }
 315        return 0;
 316}
 317
 318static int at91emac_init(struct eth_device *netdev, struct bd_info *bd)
 319{
 320        int i;
 321        u32 value;
 322        emac_device *dev;
 323        at91_emac_t *emac;
 324        at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
 325
 326        emac = (at91_emac_t *) netdev->iobase;
 327        dev = (emac_device *) netdev->priv;
 328
 329        /* PIO Disable Register */
 330        value = ATMEL_PMX_AA_EMDIO |    ATMEL_PMX_AA_EMDC |
 331                ATMEL_PMX_AA_ERXER |    ATMEL_PMX_AA_ERX1 |
 332                ATMEL_PMX_AA_ERX0 |     ATMEL_PMX_AA_ECRS |
 333                ATMEL_PMX_AA_ETX1 |     ATMEL_PMX_AA_ETX0 |
 334                ATMEL_PMX_AA_ETXEN |    ATMEL_PMX_AA_EREFCK;
 335
 336        writel(value, &pio->pioa.pdr);
 337        writel(value, &pio->pioa.mux.pio2.asr);
 338
 339#ifdef CONFIG_RMII
 340        value = ATMEL_PMX_BA_ERXCK;
 341#else
 342        value = ATMEL_PMX_BA_ERXCK |    ATMEL_PMX_BA_ECOL |
 343                ATMEL_PMX_BA_ERXDV |    ATMEL_PMX_BA_ERX3 |
 344                ATMEL_PMX_BA_ERX2 |     ATMEL_PMX_BA_ETXER |
 345                ATMEL_PMX_BA_ETX3 |     ATMEL_PMX_BA_ETX2;
 346#endif
 347        writel(value, &pio->piob.pdr);
 348        writel(value, &pio->piob.mux.pio2.bsr);
 349
 350        at91_periph_clk_enable(ATMEL_ID_EMAC);
 351
 352        writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl);
 353
 354        /* Init Ethernet buffers */
 355        for (i = 0; i < RBF_FRAMEMAX; i++) {
 356                dev->rbfdt[i].addr = (unsigned long) net_rx_packets[i];
 357                dev->rbfdt[i].size = 0;
 358        }
 359        dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
 360        dev->rbindex = 0;
 361        writel((u32) &(dev->rbfdt[0]), &emac->rbqp);
 362
 363        writel(readl(&emac->rsr) &
 364                ~(AT91_EMAC_RSR_OVR | AT91_EMAC_RSR_REC | AT91_EMAC_RSR_BNA),
 365                &emac->rsr);
 366
 367        value = AT91_EMAC_CFG_CAF |     AT91_EMAC_CFG_NBC |
 368                HCLK_DIV;
 369#ifdef CONFIG_RMII
 370        value |= AT91_EMAC_CFG_RMII;
 371#endif
 372        writel(value, &emac->cfg);
 373
 374        writel(readl(&emac->ctl) | AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE,
 375                &emac->ctl);
 376
 377        if (!at91emac_phy_init(netdev)) {
 378                at91emac_UpdateLinkSpeed(emac);
 379                return 0;
 380        }
 381        return -1;
 382}
 383
 384static void at91emac_halt(struct eth_device *netdev)
 385{
 386        at91_emac_t *emac;
 387
 388        emac = (at91_emac_t *) netdev->iobase;
 389        writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE),
 390                &emac->ctl);
 391        debug_cond(DEBUG_AT91EMAC, "halt MAC\n");
 392}
 393
 394static int at91emac_send(struct eth_device *netdev, void *packet, int length)
 395{
 396        at91_emac_t *emac;
 397
 398        emac = (at91_emac_t *) netdev->iobase;
 399
 400        while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ))
 401                ;
 402        writel((u32) packet, &emac->tar);
 403        writel(AT91_EMAC_TCR_LEN(length), &emac->tcr);
 404        while (AT91_EMAC_TCR_LEN(readl(&emac->tcr)))
 405                ;
 406        debug_cond(DEBUG_AT91EMAC, "Send %d\n", length);
 407        writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr);
 408        return 0;
 409}
 410
 411static int at91emac_recv(struct eth_device *netdev)
 412{
 413        emac_device *dev;
 414        at91_emac_t *emac;
 415        rbf_t *rbfp;
 416        int size;
 417
 418        emac = (at91_emac_t *) netdev->iobase;
 419        dev = (emac_device *) netdev->priv;
 420
 421        rbfp = &dev->rbfdt[dev->rbindex];
 422        while (rbfp->addr & RBF_OWNER)  {
 423                size = rbfp->size & RBF_SIZE;
 424                net_process_received_packet(net_rx_packets[dev->rbindex], size);
 425
 426                debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n",
 427                        dev->rbindex, size, rbfp->addr);
 428
 429                rbfp->addr &= ~RBF_OWNER;
 430                rbfp->size = 0;
 431                if (dev->rbindex < (RBF_FRAMEMAX-1))
 432                        dev->rbindex++;
 433                else
 434                        dev->rbindex = 0;
 435
 436                rbfp = &(dev->rbfdt[dev->rbindex]);
 437                if (!(rbfp->addr & RBF_OWNER))
 438                        writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC,
 439                                &emac->rsr);
 440        }
 441
 442        if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) {
 443                /* EMAC silicon bug 41.3.1 workaround 1 */
 444                writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl);
 445                writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl);
 446                dev->rbindex = 0;
 447                printf("%s: reset receiver (EMAC dead lock bug)\n",
 448                        netdev->name);
 449        }
 450        return 0;
 451}
 452
 453static int at91emac_write_hwaddr(struct eth_device *netdev)
 454{
 455        at91_emac_t *emac;
 456        emac = (at91_emac_t *) netdev->iobase;
 457
 458        at91_periph_clk_enable(ATMEL_ID_EMAC);
 459
 460        debug_cond(DEBUG_AT91EMAC,
 461                "init MAC-ADDR %02x:%02x:%02x:%02x:%02x:%02x\n",
 462                netdev->enetaddr[5], netdev->enetaddr[4], netdev->enetaddr[3],
 463                netdev->enetaddr[2], netdev->enetaddr[1], netdev->enetaddr[0]);
 464        writel( (netdev->enetaddr[0] | netdev->enetaddr[1] << 8 |
 465                        netdev->enetaddr[2] << 16 | netdev->enetaddr[3] << 24),
 466                        &emac->sa2l);
 467        writel((netdev->enetaddr[4] | netdev->enetaddr[5] << 8), &emac->sa2h);
 468        debug_cond(DEBUG_AT91EMAC, "init MAC-ADDR %x%x\n",
 469                readl(&emac->sa2h), readl(&emac->sa2l));
 470        return 0;
 471}
 472
 473int at91emac_register(struct bd_info *bis, unsigned long iobase)
 474{
 475        emac_device *emac;
 476        emac_device *emacfix;
 477        struct eth_device *dev;
 478
 479        if (iobase == 0)
 480                iobase = ATMEL_BASE_EMAC;
 481        emac = malloc(sizeof(*emac)+512);
 482        if (emac == NULL)
 483                return -1;
 484        dev = malloc(sizeof(*dev));
 485        if (dev == NULL) {
 486                free(emac);
 487                return -1;
 488        }
 489        /* alignment as per Errata (64 bytes) is insufficient! */
 490        emacfix = (emac_device *) (((unsigned long) emac + 0x1ff) & 0xFFFFFE00);
 491        memset(emacfix, 0, sizeof(emac_device));
 492
 493        memset(dev, 0, sizeof(*dev));
 494        strcpy(dev->name, "emac");
 495        dev->iobase = iobase;
 496        dev->priv = emacfix;
 497        dev->init = at91emac_init;
 498        dev->halt = at91emac_halt;
 499        dev->send = at91emac_send;
 500        dev->recv = at91emac_recv;
 501        dev->write_hwaddr = at91emac_write_hwaddr;
 502
 503        eth_register(dev);
 504
 505#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 506        int retval;
 507        struct mii_dev *mdiodev = mdio_alloc();
 508        if (!mdiodev)
 509                return -ENOMEM;
 510        strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
 511        mdiodev->read = at91emac_mii_read;
 512        mdiodev->write = at91emac_mii_write;
 513
 514        retval = mdio_register(mdiodev);
 515        if (retval < 0)
 516                return retval;
 517#endif
 518        return 1;
 519}
 520