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