uboot/drivers/net/ep93xx_eth.c
<<
>>
Prefs
   1/*
   2 * Cirrus Logic EP93xx ethernet MAC / MII driver.
   3 *
   4 * Copyright (C) 2010, 2009
   5 * Matthias Kaehlcke <matthias@kaehlcke.net>
   6 *
   7 * Copyright (C) 2004, 2005
   8 * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
   9 *
  10 * Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver,
  11 * which is
  12 *
  13 * (C) Copyright 2002 2003
  14 * Adam Bezanson, Network Audio Technologies, Inc.
  15 * <bezanson@netaudiotech.com>
  16 *
  17 * See file CREDITS for list of people who contributed to this project.
  18 *
  19 * This program is free software; you can redistribute it and/or modify
  20 * it under the terms of the GNU General Public License as published by
  21 * the Free Software Foundation; either version 2 of the License, or
  22 * (at your option) any later version.
  23 *
  24 * This program is distributed in the hope that it will be useful, but
  25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  27 * for more details.
  28 *
  29 * You should have received a copy of the GNU General Public License along
  30 * with this program; if not, write to the Free Software Foundation, Inc.,
  31 * 675 Mass Ave, Cambridge, MA 02139, USA.
  32 */
  33
  34#include <command.h>
  35#include <common.h>
  36#include <asm/arch/ep93xx.h>
  37#include <asm/io.h>
  38#include <malloc.h>
  39#include <miiphy.h>
  40#include <linux/types.h>
  41#include "ep93xx_eth.h"
  42
  43#define GET_PRIV(eth_dev)       ((struct ep93xx_priv *)(eth_dev)->priv)
  44#define GET_REGS(eth_dev)       (GET_PRIV(eth_dev)->regs)
  45
  46/* ep93xx_miiphy ops forward declarations */
  47static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
  48                        unsigned char const reg, unsigned short * const value);
  49static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
  50                        unsigned char const reg, unsigned short const value);
  51
  52#if defined(EP93XX_MAC_DEBUG)
  53/**
  54 * Dump ep93xx_mac values to the terminal.
  55 */
  56static void dump_dev(struct eth_device *dev)
  57{
  58        struct ep93xx_priv *priv = GET_PRIV(dev);
  59        int i;
  60
  61        printf("\ndump_dev()\n");
  62        printf("  rx_dq.base         %p\n", priv->rx_dq.base);
  63        printf("  rx_dq.current      %p\n", priv->rx_dq.current);
  64        printf("  rx_dq.end          %p\n", priv->rx_dq.end);
  65        printf("  rx_sq.base         %p\n", priv->rx_sq.base);
  66        printf("  rx_sq.current      %p\n", priv->rx_sq.current);
  67        printf("  rx_sq.end          %p\n", priv->rx_sq.end);
  68
  69        for (i = 0; i < NUMRXDESC; i++)
  70                printf("  rx_buffer[%2.d]      %p\n", i, NetRxPackets[i]);
  71
  72        printf("  tx_dq.base         %p\n", priv->tx_dq.base);
  73        printf("  tx_dq.current      %p\n", priv->tx_dq.current);
  74        printf("  tx_dq.end          %p\n", priv->tx_dq.end);
  75        printf("  tx_sq.base         %p\n", priv->tx_sq.base);
  76        printf("  tx_sq.current      %p\n", priv->tx_sq.current);
  77        printf("  tx_sq.end          %p\n", priv->tx_sq.end);
  78}
  79
  80/**
  81 * Dump all RX status queue entries to the terminal.
  82 */
  83static void dump_rx_status_queue(struct eth_device *dev)
  84{
  85        struct ep93xx_priv *priv = GET_PRIV(dev);
  86        int i;
  87
  88        printf("\ndump_rx_status_queue()\n");
  89        printf("  descriptor address     word1           word2\n");
  90        for (i = 0; i < NUMRXDESC; i++) {
  91                printf("  [ %p ]             %08X        %08X\n",
  92                        priv->rx_sq.base + i,
  93                        (priv->rx_sq.base + i)->word1,
  94                        (priv->rx_sq.base + i)->word2);
  95        }
  96}
  97
  98/**
  99 * Dump all RX descriptor queue entries to the terminal.
 100 */
 101static void dump_rx_descriptor_queue(struct eth_device *dev)
 102{
 103        struct ep93xx_priv *priv = GET_PRIV(dev);
 104        int i;
 105
 106        printf("\ndump_rx_descriptor_queue()\n");
 107        printf("  descriptor address     word1           word2\n");
 108        for (i = 0; i < NUMRXDESC; i++) {
 109                printf("  [ %p ]             %08X        %08X\n",
 110                        priv->rx_dq.base + i,
 111                        (priv->rx_dq.base + i)->word1,
 112                        (priv->rx_dq.base + i)->word2);
 113        }
 114}
 115
 116/**
 117 * Dump all TX descriptor queue entries to the terminal.
 118 */
 119static void dump_tx_descriptor_queue(struct eth_device *dev)
 120{
 121        struct ep93xx_priv *priv = GET_PRIV(dev);
 122        int i;
 123
 124        printf("\ndump_tx_descriptor_queue()\n");
 125        printf("  descriptor address     word1           word2\n");
 126        for (i = 0; i < NUMTXDESC; i++) {
 127                printf("  [ %p ]             %08X        %08X\n",
 128                        priv->tx_dq.base + i,
 129                        (priv->tx_dq.base + i)->word1,
 130                        (priv->tx_dq.base + i)->word2);
 131        }
 132}
 133
 134/**
 135 * Dump all TX status queue entries to the terminal.
 136 */
 137static void dump_tx_status_queue(struct eth_device *dev)
 138{
 139        struct ep93xx_priv *priv = GET_PRIV(dev);
 140        int i;
 141
 142        printf("\ndump_tx_status_queue()\n");
 143        printf("  descriptor address     word1\n");
 144        for (i = 0; i < NUMTXDESC; i++) {
 145                printf("  [ %p ]             %08X\n",
 146                        priv->rx_sq.base + i,
 147                        (priv->rx_sq.base + i)->word1);
 148        }
 149}
 150#else
 151#define dump_dev(x)
 152#define dump_rx_descriptor_queue(x)
 153#define dump_rx_status_queue(x)
 154#define dump_tx_descriptor_queue(x)
 155#define dump_tx_status_queue(x)
 156#endif  /* defined(EP93XX_MAC_DEBUG) */
 157
 158/**
 159 * Reset the EP93xx MAC by twiddling the soft reset bit and spinning until
 160 * it's cleared.
 161 */
 162static void ep93xx_mac_reset(struct eth_device *dev)
 163{
 164        struct mac_regs *mac = GET_REGS(dev);
 165        uint32_t value;
 166
 167        debug("+ep93xx_mac_reset");
 168
 169        value = readl(&mac->selfctl);
 170        value |= SELFCTL_RESET;
 171        writel(value, &mac->selfctl);
 172
 173        while (readl(&mac->selfctl) & SELFCTL_RESET)
 174                ; /* noop */
 175
 176        debug("-ep93xx_mac_reset");
 177}
 178
 179/* Eth device open */
 180static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd)
 181{
 182        struct ep93xx_priv *priv = GET_PRIV(dev);
 183        struct mac_regs *mac = GET_REGS(dev);
 184        uchar *mac_addr = dev->enetaddr;
 185        int i;
 186
 187        debug("+ep93xx_eth_open");
 188
 189        /* Reset the MAC */
 190        ep93xx_mac_reset(dev);
 191
 192        /* Reset the descriptor queues' current and end address values */
 193        priv->tx_dq.current = priv->tx_dq.base;
 194        priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC);
 195
 196        priv->tx_sq.current = priv->tx_sq.base;
 197        priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC);
 198
 199        priv->rx_dq.current = priv->rx_dq.base;
 200        priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC);
 201
 202        priv->rx_sq.current = priv->rx_sq.base;
 203        priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC);
 204
 205        /*
 206         * Set the transmit descriptor and status queues' base address,
 207         * current address, and length registers.  Set the maximum frame
 208         * length and threshold. Enable the transmit descriptor processor.
 209         */
 210        writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd);
 211        writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd);
 212        writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen);
 213
 214        writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd);
 215        writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd);
 216        writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen);
 217
 218        writel(0x00040000, &mac->txdthrshld);
 219        writel(0x00040000, &mac->txststhrshld);
 220
 221        writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen);
 222        writel(BMCTL_TXEN, &mac->bmctl);
 223
 224        /*
 225         * Set the receive descriptor and status queues' base address,
 226         * current address, and length registers.  Enable the receive
 227         * descriptor processor.
 228         */
 229        writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd);
 230        writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd);
 231        writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen);
 232
 233        writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd);
 234        writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd);
 235        writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen);
 236
 237        writel(0x00040000, &mac->rxdthrshld);
 238
 239        writel(BMCTL_RXEN, &mac->bmctl);
 240
 241        writel(0x00040000, &mac->rxststhrshld);
 242
 243        /* Wait until the receive descriptor processor is active */
 244        while (!(readl(&mac->bmsts) & BMSTS_RXACT))
 245                ; /* noop */
 246
 247        /*
 248         * Initialize the RX descriptor queue. Clear the TX descriptor queue.
 249         * Clear the RX and TX status queues. Enqueue the RX descriptor and
 250         * status entries to the MAC.
 251         */
 252        for (i = 0; i < NUMRXDESC; i++) {
 253                /* set buffer address */
 254                (priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i];
 255
 256                /* set buffer length, clear buffer index and NSOF */
 257                (priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN;
 258        }
 259
 260        memset(priv->tx_dq.base, 0,
 261                (sizeof(struct tx_descriptor) * NUMTXDESC));
 262        memset(priv->rx_sq.base, 0,
 263                (sizeof(struct rx_status) * NUMRXDESC));
 264        memset(priv->tx_sq.base, 0,
 265                (sizeof(struct tx_status) * NUMTXDESC));
 266
 267        writel(NUMRXDESC, &mac->rxdqenq);
 268        writel(NUMRXDESC, &mac->rxstsqenq);
 269
 270        /* Set the primary MAC address */
 271        writel(AFP_IAPRIMARY, &mac->afp);
 272        writel(mac_addr[0] | (mac_addr[1] << 8) |
 273                (mac_addr[2] << 16) | (mac_addr[3] << 24),
 274                &mac->indad);
 275        writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper);
 276
 277        /* Turn on RX and TX */
 278        writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON |
 279                RXCTL_RCRCA | RXCTL_MA, &mac->rxctl);
 280        writel(TXCTL_STXON, &mac->txctl);
 281
 282        /* Dump data structures if we're debugging */
 283        dump_dev(dev);
 284        dump_rx_descriptor_queue(dev);
 285        dump_rx_status_queue(dev);
 286        dump_tx_descriptor_queue(dev);
 287        dump_tx_status_queue(dev);
 288
 289        debug("-ep93xx_eth_open");
 290
 291        return 1;
 292}
 293
 294/**
 295 * Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL
 296 * registers.
 297 */
 298static void ep93xx_eth_close(struct eth_device *dev)
 299{
 300        struct mac_regs *mac = GET_REGS(dev);
 301
 302        debug("+ep93xx_eth_close");
 303
 304        writel(0x00000000, &mac->rxctl);
 305        writel(0x00000000, &mac->txctl);
 306
 307        debug("-ep93xx_eth_close");
 308}
 309
 310/**
 311 * Copy a frame of data from the MAC into the protocol layer for further
 312 * processing.
 313 */
 314static int ep93xx_eth_rcv_packet(struct eth_device *dev)
 315{
 316        struct mac_regs *mac = GET_REGS(dev);
 317        struct ep93xx_priv *priv = GET_PRIV(dev);
 318        int len = -1;
 319
 320        debug("+ep93xx_eth_rcv_packet");
 321
 322        if (RX_STATUS_RFP(priv->rx_sq.current)) {
 323                if (RX_STATUS_RWE(priv->rx_sq.current)) {
 324                        /*
 325                         * We have a good frame. Extract the frame's length
 326                         * from the current rx_status_queue entry, and copy
 327                         * the frame's data into NetRxPackets[] of the
 328                         * protocol stack. We track the total number of
 329                         * bytes in the frame (nbytes_frame) which will be
 330                         * used when we pass the data off to the protocol
 331                         * layer via NetReceive().
 332                         */
 333                        len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
 334
 335                        NetReceive((uchar *)priv->rx_dq.current->word1, len);
 336
 337                        debug("reporting %d bytes...\n", len);
 338                } else {
 339                        /* Do we have an erroneous packet? */
 340                        error("packet rx error, status %08X %08X",
 341                                priv->rx_sq.current->word1,
 342                                priv->rx_sq.current->word2);
 343                        dump_rx_descriptor_queue(dev);
 344                        dump_rx_status_queue(dev);
 345                }
 346
 347                /*
 348                 * Clear the associated status queue entry, and
 349                 * increment our current pointers to the next RX
 350                 * descriptor and status queue entries (making sure
 351                 * we wrap properly).
 352                 */
 353                memset((void *)priv->rx_sq.current, 0,
 354                        sizeof(struct rx_status));
 355
 356                priv->rx_sq.current++;
 357                if (priv->rx_sq.current >= priv->rx_sq.end)
 358                        priv->rx_sq.current = priv->rx_sq.base;
 359
 360                priv->rx_dq.current++;
 361                if (priv->rx_dq.current >= priv->rx_dq.end)
 362                        priv->rx_dq.current = priv->rx_dq.base;
 363
 364                /*
 365                 * Finally, return the RX descriptor and status entries
 366                 * back to the MAC engine, and loop again, checking for
 367                 * more descriptors to process.
 368                 */
 369                writel(1, &mac->rxdqenq);
 370                writel(1, &mac->rxstsqenq);
 371        } else {
 372                len = 0;
 373        }
 374
 375        debug("-ep93xx_eth_rcv_packet %d", len);
 376        return len;
 377}
 378
 379/**
 380 * Send a block of data via ethernet.
 381 */
 382static int ep93xx_eth_send_packet(struct eth_device *dev,
 383                                void * const packet, int const length)
 384{
 385        struct mac_regs *mac = GET_REGS(dev);
 386        struct ep93xx_priv *priv = GET_PRIV(dev);
 387        int ret = -1;
 388
 389        debug("+ep93xx_eth_send_packet");
 390
 391        /* Parameter check */
 392        BUG_ON(packet == NULL);
 393
 394        /*
 395         * Initialize the TX descriptor queue with the new packet's info.
 396         * Clear the associated status queue entry. Enqueue the packet
 397         * to the MAC for transmission.
 398         */
 399
 400        /* set buffer address */
 401        priv->tx_dq.current->word1 = (uint32_t)packet;
 402
 403        /* set buffer length and EOF bit */
 404        priv->tx_dq.current->word2 = length | TX_DESC_EOF;
 405
 406        /* clear tx status */
 407        priv->tx_sq.current->word1 = 0;
 408
 409        /* enqueue the TX descriptor */
 410        writel(1, &mac->txdqenq);
 411
 412        /* wait for the frame to become processed */
 413        while (!TX_STATUS_TXFP(priv->tx_sq.current))
 414                ; /* noop */
 415
 416        if (!TX_STATUS_TXWE(priv->tx_sq.current)) {
 417                error("packet tx error, status %08X",
 418                        priv->tx_sq.current->word1);
 419                dump_tx_descriptor_queue(dev);
 420                dump_tx_status_queue(dev);
 421
 422                /* TODO: Add better error handling? */
 423                goto eth_send_out;
 424        }
 425
 426        ret = 0;
 427        /* Fall through */
 428
 429eth_send_out:
 430        debug("-ep93xx_eth_send_packet %d", ret);
 431        return ret;
 432}
 433
 434#if defined(CONFIG_MII)
 435int ep93xx_miiphy_initialize(bd_t * const bd)
 436{
 437        miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write);
 438        return 0;
 439}
 440#endif
 441
 442/**
 443 * Initialize the EP93xx MAC.  The MAC hardware is reset.  Buffers are
 444 * allocated, if necessary, for the TX and RX descriptor and status queues,
 445 * as well as for received packets.  The EP93XX MAC hardware is initialized.
 446 * Transmit and receive operations are enabled.
 447 */
 448int ep93xx_eth_initialize(u8 dev_num, int base_addr)
 449{
 450        int ret = -1;
 451        struct eth_device *dev;
 452        struct ep93xx_priv *priv;
 453
 454        debug("+ep93xx_eth_initialize");
 455
 456        priv = malloc(sizeof(*priv));
 457        if (!priv) {
 458                error("malloc() failed");
 459                goto eth_init_failed_0;
 460        }
 461        memset(priv, 0, sizeof(*priv));
 462
 463        priv->regs = (struct mac_regs *)base_addr;
 464
 465        priv->tx_dq.base = calloc(NUMTXDESC,
 466                                sizeof(struct tx_descriptor));
 467        if (priv->tx_dq.base == NULL) {
 468                error("calloc() failed");
 469                goto eth_init_failed_1;
 470        }
 471
 472        priv->tx_sq.base = calloc(NUMTXDESC,
 473                                sizeof(struct tx_status));
 474        if (priv->tx_sq.base == NULL) {
 475                error("calloc() failed");
 476                goto eth_init_failed_2;
 477        }
 478
 479        priv->rx_dq.base = calloc(NUMRXDESC,
 480                                sizeof(struct rx_descriptor));
 481        if (priv->rx_dq.base == NULL) {
 482                error("calloc() failed");
 483                goto eth_init_failed_3;
 484        }
 485
 486        priv->rx_sq.base = calloc(NUMRXDESC,
 487                                sizeof(struct rx_status));
 488        if (priv->rx_sq.base == NULL) {
 489                error("calloc() failed");
 490                goto eth_init_failed_4;
 491        }
 492
 493        dev = malloc(sizeof *dev);
 494        if (dev == NULL) {
 495                error("malloc() failed");
 496                goto eth_init_failed_5;
 497        }
 498        memset(dev, 0, sizeof *dev);
 499
 500        dev->iobase = base_addr;
 501        dev->priv = priv;
 502        dev->init = ep93xx_eth_open;
 503        dev->halt = ep93xx_eth_close;
 504        dev->send = ep93xx_eth_send_packet;
 505        dev->recv = ep93xx_eth_rcv_packet;
 506
 507        sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
 508
 509        eth_register(dev);
 510
 511        /* Done! */
 512        ret = 1;
 513        goto eth_init_done;
 514
 515eth_init_failed_5:
 516        free(priv->rx_sq.base);
 517        /* Fall through */
 518
 519eth_init_failed_4:
 520        free(priv->rx_dq.base);
 521        /* Fall through */
 522
 523eth_init_failed_3:
 524        free(priv->tx_sq.base);
 525        /* Fall through */
 526
 527eth_init_failed_2:
 528        free(priv->tx_dq.base);
 529        /* Fall through */
 530
 531eth_init_failed_1:
 532        free(priv);
 533        /* Fall through */
 534
 535eth_init_failed_0:
 536        /* Fall through */
 537
 538eth_init_done:
 539        debug("-ep93xx_eth_initialize %d", ret);
 540        return ret;
 541}
 542
 543#if defined(CONFIG_MII)
 544
 545/**
 546 * Maximum MII address we support
 547 */
 548#define MII_ADDRESS_MAX                 31
 549
 550/**
 551 * Maximum MII register address we support
 552 */
 553#define MII_REGISTER_MAX                31
 554
 555/**
 556 * Read a 16-bit value from an MII register.
 557 */
 558static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
 559                        unsigned char const reg, unsigned short * const value)
 560{
 561        struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
 562        int ret = -1;
 563        uint32_t self_ctl;
 564
 565        debug("+ep93xx_miiphy_read");
 566
 567        /* Parameter checks */
 568        BUG_ON(dev == NULL);
 569        BUG_ON(addr > MII_ADDRESS_MAX);
 570        BUG_ON(reg > MII_REGISTER_MAX);
 571        BUG_ON(value == NULL);
 572
 573        /*
 574         * Save the current SelfCTL register value.  Set MAC to suppress
 575         * preamble bits.  Wait for any previous MII command to complete
 576         * before issuing the new command.
 577         */
 578        self_ctl = readl(&mac->selfctl);
 579#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
 580        writel(self_ctl & ~(1 << 8), &mac->selfctl);
 581#endif  /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
 582
 583        while (readl(&mac->miists) & MIISTS_BUSY)
 584                ; /* noop */
 585
 586        /*
 587         * Issue the MII 'read' command.  Wait for the command to complete.
 588         * Read the MII data value.
 589         */
 590        writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
 591                &mac->miicmd);
 592        while (readl(&mac->miists) & MIISTS_BUSY)
 593                ; /* noop */
 594
 595        *value = (unsigned short)readl(&mac->miidata);
 596
 597        /* Restore the saved SelfCTL value and return. */
 598        writel(self_ctl, &mac->selfctl);
 599
 600        ret = 0;
 601        /* Fall through */
 602
 603        debug("-ep93xx_miiphy_read");
 604        return ret;
 605}
 606
 607/**
 608 * Write a 16-bit value to an MII register.
 609 */
 610static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
 611                        unsigned char const reg, unsigned short const value)
 612{
 613        struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
 614        int ret = -1;
 615        uint32_t self_ctl;
 616
 617        debug("+ep93xx_miiphy_write");
 618
 619        /* Parameter checks */
 620        BUG_ON(dev == NULL);
 621        BUG_ON(addr > MII_ADDRESS_MAX);
 622        BUG_ON(reg > MII_REGISTER_MAX);
 623
 624        /*
 625         * Save the current SelfCTL register value.  Set MAC to suppress
 626         * preamble bits.  Wait for any previous MII command to complete
 627         * before issuing the new command.
 628         */
 629        self_ctl = readl(&mac->selfctl);
 630#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
 631        writel(self_ctl & ~(1 << 8), &mac->selfctl);
 632#endif  /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
 633
 634        while (readl(&mac->miists) & MIISTS_BUSY)
 635                ; /* noop */
 636
 637        /* Issue the MII 'write' command.  Wait for the command to complete. */
 638        writel((uint32_t)value, &mac->miidata);
 639        writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
 640                &mac->miicmd);
 641        while (readl(&mac->miists) & MIISTS_BUSY)
 642                ; /* noop */
 643
 644        /* Restore the saved SelfCTL value and return. */
 645        writel(self_ctl, &mac->selfctl);
 646
 647        ret = 0;
 648        /* Fall through */
 649
 650        debug("-ep93xx_miiphy_write");
 651        return ret;
 652}
 653#endif  /* defined(CONFIG_MII) */
 654