uboot/drivers/net/xilinx_axi_emac.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Michal Simek <monstr@monstr.eu>
   3 * Copyright (C) 2011 PetaLogix
   4 * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25#include <config.h>
  26#include <common.h>
  27#include <net.h>
  28#include <malloc.h>
  29#include <asm/io.h>
  30#include <phy.h>
  31#include <miiphy.h>
  32
  33#if !defined(CONFIG_PHYLIB)
  34# error AXI_ETHERNET requires PHYLIB
  35#endif
  36
  37/* Link setup */
  38#define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */
  39#define XAE_EMMC_LINKSPD_10     0x00000000 /* Link Speed mask for 10 Mbit */
  40#define XAE_EMMC_LINKSPD_100    0x40000000 /* Link Speed mask for 100 Mbit */
  41#define XAE_EMMC_LINKSPD_1000   0x80000000 /* Link Speed mask for 1000 Mbit */
  42
  43/* Interrupt Status/Enable/Mask Registers bit definitions */
  44#define XAE_INT_RXRJECT_MASK    0x00000008 /* Rx frame rejected */
  45#define XAE_INT_MGTRDY_MASK     0x00000080 /* MGT clock Lock */
  46
  47/* Receive Configuration Word 1 (RCW1) Register bit definitions */
  48#define XAE_RCW1_RX_MASK        0x10000000 /* Receiver enable */
  49
  50/* Transmitter Configuration (TC) Register bit definitions */
  51#define XAE_TC_TX_MASK          0x10000000 /* Transmitter enable */
  52
  53#define XAE_UAW1_UNICASTADDR_MASK       0x0000FFFF
  54
  55/* MDIO Management Configuration (MC) Register bit definitions */
  56#define XAE_MDIO_MC_MDIOEN_MASK         0x00000040 /* MII management enable*/
  57
  58/* MDIO Management Control Register (MCR) Register bit definitions */
  59#define XAE_MDIO_MCR_PHYAD_MASK         0x1F000000 /* Phy Address Mask */
  60#define XAE_MDIO_MCR_PHYAD_SHIFT        24         /* Phy Address Shift */
  61#define XAE_MDIO_MCR_REGAD_MASK         0x001F0000 /* Reg Address Mask */
  62#define XAE_MDIO_MCR_REGAD_SHIFT        16         /* Reg Address Shift */
  63#define XAE_MDIO_MCR_OP_READ_MASK       0x00008000 /* Op Code Read Mask */
  64#define XAE_MDIO_MCR_OP_WRITE_MASK      0x00004000 /* Op Code Write Mask */
  65#define XAE_MDIO_MCR_INITIATE_MASK      0x00000800 /* Ready Mask */
  66#define XAE_MDIO_MCR_READY_MASK         0x00000080 /* Ready Mask */
  67
  68#define XAE_MDIO_DIV_DFT        29      /* Default MDIO clock divisor */
  69
  70/* DMA macros */
  71/* Bitmasks of XAXIDMA_CR_OFFSET register */
  72#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /* Start/stop DMA channel */
  73#define XAXIDMA_CR_RESET_MASK   0x00000004 /* Reset DMA engine */
  74
  75/* Bitmasks of XAXIDMA_SR_OFFSET register */
  76#define XAXIDMA_HALTED_MASK     0x00000001  /* DMA channel halted */
  77
  78/* Bitmask for interrupts */
  79#define XAXIDMA_IRQ_IOC_MASK    0x00001000 /* Completion intr */
  80#define XAXIDMA_IRQ_DELAY_MASK  0x00002000 /* Delay interrupt */
  81#define XAXIDMA_IRQ_ALL_MASK    0x00007000 /* All interrupts */
  82
  83/* Bitmasks of XAXIDMA_BD_CTRL_OFFSET register */
  84#define XAXIDMA_BD_CTRL_TXSOF_MASK      0x08000000 /* First tx packet */
  85#define XAXIDMA_BD_CTRL_TXEOF_MASK      0x04000000 /* Last tx packet */
  86
  87#define DMAALIGN        128
  88
  89static u8 rxframe[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN)));
  90
  91/* Reflect dma offsets */
  92struct axidma_reg {
  93        u32 control; /* DMACR */
  94        u32 status; /* DMASR */
  95        u32 current; /* CURDESC */
  96        u32 reserved;
  97        u32 tail; /* TAILDESC */
  98};
  99
 100/* Private driver structures */
 101struct axidma_priv {
 102        struct axidma_reg *dmatx;
 103        struct axidma_reg *dmarx;
 104        int phyaddr;
 105
 106        struct phy_device *phydev;
 107        struct mii_dev *bus;
 108};
 109
 110/* BD descriptors */
 111struct axidma_bd {
 112        u32 next;       /* Next descriptor pointer */
 113        u32 reserved1;
 114        u32 phys;       /* Buffer address */
 115        u32 reserved2;
 116        u32 reserved3;
 117        u32 reserved4;
 118        u32 cntrl;      /* Control */
 119        u32 status;     /* Status */
 120        u32 app0;
 121        u32 app1;       /* TX start << 16 | insert */
 122        u32 app2;       /* TX csum seed */
 123        u32 app3;
 124        u32 app4;
 125        u32 sw_id_offset;
 126        u32 reserved5;
 127        u32 reserved6;
 128};
 129
 130/* Static BDs - driver uses only one BD */
 131static struct axidma_bd tx_bd __attribute((aligned(DMAALIGN)));
 132static struct axidma_bd rx_bd __attribute((aligned(DMAALIGN)));
 133
 134struct axi_regs {
 135        u32 reserved[3];
 136        u32 is; /* 0xC: Interrupt status */
 137        u32 reserved2;
 138        u32 ie; /* 0x14: Interrupt enable */
 139        u32 reserved3[251];
 140        u32 rcw1; /* 0x404: Rx Configuration Word 1 */
 141        u32 tc; /* 0x408: Tx Configuration */
 142        u32 reserved4;
 143        u32 emmc; /* 0x410: EMAC mode configuration */
 144        u32 reserved5[59];
 145        u32 mdio_mc; /* 0x500: MII Management Config */
 146        u32 mdio_mcr; /* 0x504: MII Management Control */
 147        u32 mdio_mwd; /* 0x508: MII Management Write Data */
 148        u32 mdio_mrd; /* 0x50C: MII Management Read Data */
 149        u32 reserved6[124];
 150        u32 uaw0; /* 0x700: Unicast address word 0 */
 151        u32 uaw1; /* 0x704: Unicast address word 1 */
 152};
 153
 154/* Use MII register 1 (MII status register) to detect PHY */
 155#define PHY_DETECT_REG  1
 156
 157/*
 158 * Mask used to verify certain PHY features (or register contents)
 159 * in the register above:
 160 *  0x1000: 10Mbps full duplex support
 161 *  0x0800: 10Mbps half duplex support
 162 *  0x0008: Auto-negotiation support
 163 */
 164#define PHY_DETECT_MASK 0x1808
 165
 166static inline int mdio_wait(struct eth_device *dev)
 167{
 168        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 169        u32 timeout = 200;
 170
 171        /* Wait till MDIO interface is ready to accept a new transaction. */
 172        while (timeout && (!(in_be32(&regs->mdio_mcr)
 173                                                & XAE_MDIO_MCR_READY_MASK))) {
 174                timeout--;
 175                udelay(1);
 176        }
 177        if (!timeout) {
 178                printf("%s: Timeout\n", __func__);
 179                return 1;
 180        }
 181        return 0;
 182}
 183
 184static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
 185                                                                u16 *val)
 186{
 187        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 188        u32 mdioctrlreg = 0;
 189
 190        if (mdio_wait(dev))
 191                return 1;
 192
 193        mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
 194                        XAE_MDIO_MCR_PHYAD_MASK) |
 195                        ((registernum << XAE_MDIO_MCR_REGAD_SHIFT)
 196                        & XAE_MDIO_MCR_REGAD_MASK) |
 197                        XAE_MDIO_MCR_INITIATE_MASK |
 198                        XAE_MDIO_MCR_OP_READ_MASK;
 199
 200        out_be32(&regs->mdio_mcr, mdioctrlreg);
 201
 202        if (mdio_wait(dev))
 203                return 1;
 204
 205        /* Read data */
 206        *val = in_be32(&regs->mdio_mrd);
 207        return 0;
 208}
 209
 210static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum,
 211                                                                u32 data)
 212{
 213        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 214        u32 mdioctrlreg = 0;
 215
 216        if (mdio_wait(dev))
 217                return 1;
 218
 219        mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
 220                        XAE_MDIO_MCR_PHYAD_MASK) |
 221                        ((registernum << XAE_MDIO_MCR_REGAD_SHIFT)
 222                        & XAE_MDIO_MCR_REGAD_MASK) |
 223                        XAE_MDIO_MCR_INITIATE_MASK |
 224                        XAE_MDIO_MCR_OP_WRITE_MASK;
 225
 226        /* Write data */
 227        out_be32(&regs->mdio_mwd, data);
 228
 229        out_be32(&regs->mdio_mcr, mdioctrlreg);
 230
 231        if (mdio_wait(dev))
 232                return 1;
 233
 234        return 0;
 235}
 236
 237/* Setting axi emac and phy to proper setting */
 238static int setup_phy(struct eth_device *dev)
 239{
 240        u16 phyreg;
 241        u32 i, speed, emmc_reg, ret;
 242        struct axidma_priv *priv = dev->priv;
 243        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 244        struct phy_device *phydev;
 245
 246        u32 supported = SUPPORTED_10baseT_Half |
 247                        SUPPORTED_10baseT_Full |
 248                        SUPPORTED_100baseT_Half |
 249                        SUPPORTED_100baseT_Full |
 250                        SUPPORTED_1000baseT_Half |
 251                        SUPPORTED_1000baseT_Full;
 252
 253        if (priv->phyaddr == -1) {
 254                /* Detect the PHY address */
 255                for (i = 31; i >= 0; i--) {
 256                        ret = phyread(dev, i, PHY_DETECT_REG, &phyreg);
 257                        if (!ret && (phyreg != 0xFFFF) &&
 258                        ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
 259                                /* Found a valid PHY address */
 260                                priv->phyaddr = i;
 261                                debug("axiemac: Found valid phy address, %x\n",
 262                                                                        phyreg);
 263                                break;
 264                        }
 265                }
 266        }
 267
 268        /* Interface - look at tsec */
 269        phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
 270
 271        phydev->supported &= supported;
 272        phydev->advertising = phydev->supported;
 273        priv->phydev = phydev;
 274        phy_config(phydev);
 275        phy_startup(phydev);
 276
 277        switch (phydev->speed) {
 278        case 1000:
 279                speed = XAE_EMMC_LINKSPD_1000;
 280                break;
 281        case 100:
 282                speed = XAE_EMMC_LINKSPD_100;
 283                break;
 284        case 10:
 285                speed = XAE_EMMC_LINKSPD_10;
 286                break;
 287        default:
 288                return 0;
 289        }
 290
 291        /* Setup the emac for the phy speed */
 292        emmc_reg = in_be32(&regs->emmc);
 293        emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
 294        emmc_reg |= speed;
 295
 296        /* Write new speed setting out to Axi Ethernet */
 297        out_be32(&regs->emmc, emmc_reg);
 298
 299        /*
 300        * Setting the operating speed of the MAC needs a delay. There
 301        * doesn't seem to be register to poll, so please consider this
 302        * during your application design.
 303        */
 304        udelay(1);
 305
 306        return 1;
 307}
 308
 309/* STOP DMA transfers */
 310static void axiemac_halt(struct eth_device *dev)
 311{
 312        struct axidma_priv *priv = dev->priv;
 313        u32 temp;
 314
 315        /* Stop the hardware */
 316        temp = in_be32(&priv->dmatx->control);
 317        temp &= ~XAXIDMA_CR_RUNSTOP_MASK;
 318        out_be32(&priv->dmatx->control, temp);
 319
 320        temp = in_be32(&priv->dmarx->control);
 321        temp &= ~XAXIDMA_CR_RUNSTOP_MASK;
 322        out_be32(&priv->dmarx->control, temp);
 323
 324        debug("axiemac: Halted\n");
 325}
 326
 327static int axi_ethernet_init(struct eth_device *dev)
 328{
 329        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 330        u32 timeout = 200;
 331
 332        /*
 333         * Check the status of the MgtRdy bit in the interrupt status
 334         * registers. This must be done to allow the MGT clock to become stable
 335         * for the Sgmii and 1000BaseX PHY interfaces. No other register reads
 336         * will be valid until this bit is valid.
 337         * The bit is always a 1 for all other PHY interfaces.
 338         */
 339        while (timeout && (!(in_be32(&regs->is) & XAE_INT_MGTRDY_MASK))) {
 340                timeout--;
 341                udelay(1);
 342        }
 343        if (!timeout) {
 344                printf("%s: Timeout\n", __func__);
 345                return 1;
 346        }
 347
 348        /* Stop the device and reset HW */
 349        /* Disable interrupts */
 350        out_be32(&regs->ie, 0);
 351
 352        /* Disable the receiver */
 353        out_be32(&regs->rcw1, in_be32(&regs->rcw1) & ~XAE_RCW1_RX_MASK);
 354
 355        /*
 356         * Stopping the receiver in mid-packet causes a dropped packet
 357         * indication from HW. Clear it.
 358         */
 359        /* Set the interrupt status register to clear the interrupt */
 360        out_be32(&regs->is, XAE_INT_RXRJECT_MASK);
 361
 362        /* Setup HW */
 363        /* Set default MDIO divisor */
 364        out_be32(&regs->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK);
 365
 366        debug("axiemac: InitHw done\n");
 367        return 0;
 368}
 369
 370static int axiemac_setup_mac(struct eth_device *dev)
 371{
 372        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 373
 374        /* Set the MAC address */
 375        int val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) |
 376                (dev->enetaddr[1] << 8) | (dev->enetaddr[0]));
 377        out_be32(&regs->uaw0, val);
 378
 379        val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ;
 380        val |= in_be32(&regs->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK;
 381        out_be32(&regs->uaw1, val);
 382        return 0;
 383}
 384
 385/* Reset DMA engine */
 386static void axi_dma_init(struct eth_device *dev)
 387{
 388        struct axidma_priv *priv = dev->priv;
 389        u32 timeout = 500;
 390
 391        /* Reset the engine so the hardware starts from a known state */
 392        out_be32(&priv->dmatx->control, XAXIDMA_CR_RESET_MASK);
 393        out_be32(&priv->dmarx->control, XAXIDMA_CR_RESET_MASK);
 394
 395        /* At the initialization time, hardware should finish reset quickly */
 396        while (timeout--) {
 397                /* Check transmit/receive channel */
 398                /* Reset is done when the reset bit is low */
 399                if (!(in_be32(&priv->dmatx->control) |
 400                                in_be32(&priv->dmarx->control))
 401                                                & XAXIDMA_CR_RESET_MASK) {
 402                        break;
 403                }
 404        }
 405        if (!timeout)
 406                printf("%s: Timeout\n", __func__);
 407}
 408
 409static int axiemac_init(struct eth_device *dev, bd_t * bis)
 410{
 411        struct axidma_priv *priv = dev->priv;
 412        struct axi_regs *regs = (struct axi_regs *)dev->iobase;
 413        u32 temp;
 414
 415        debug("axiemac: Init started\n");
 416        /*
 417         * Initialize AXIDMA engine. AXIDMA engine must be initialized before
 418         * AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is
 419         * reset, and since AXIDMA reset line is connected to AxiEthernet, this
 420         * would ensure a reset of AxiEthernet.
 421         */
 422        axi_dma_init(dev);
 423
 424        /* Initialize AxiEthernet hardware. */
 425        if (axi_ethernet_init(dev))
 426                return -1;
 427
 428        /* Disable all RX interrupts before RxBD space setup */
 429        temp = in_be32(&priv->dmarx->control);
 430        temp &= ~XAXIDMA_IRQ_ALL_MASK;
 431        out_be32(&priv->dmarx->control, temp);
 432
 433        /* Start DMA RX channel. Now it's ready to receive data.*/
 434        out_be32(&priv->dmarx->current, (u32)&rx_bd);
 435
 436        /* Setup the BD. */
 437        memset(&rx_bd, 0, sizeof(rx_bd));
 438        rx_bd.next = (u32)&rx_bd;
 439        rx_bd.phys = (u32)&rxframe;
 440        rx_bd.cntrl = sizeof(rxframe);
 441        /* Flush the last BD so DMA core could see the updates */
 442        flush_cache((u32)&rx_bd, sizeof(rx_bd));
 443
 444        /* It is necessary to flush rxframe because if you don't do it
 445         * then cache can contain uninitialized data */
 446        flush_cache((u32)&rxframe, sizeof(rxframe));
 447
 448        /* Start the hardware */
 449        temp = in_be32(&priv->dmarx->control);
 450        temp |= XAXIDMA_CR_RUNSTOP_MASK;
 451        out_be32(&priv->dmarx->control, temp);
 452
 453        /* Rx BD is ready - start */
 454        out_be32(&priv->dmarx->tail, (u32)&rx_bd);
 455
 456        /* Enable TX */
 457        out_be32(&regs->tc, XAE_TC_TX_MASK);
 458        /* Enable RX */
 459        out_be32(&regs->rcw1, XAE_RCW1_RX_MASK);
 460
 461        /* PHY setup */
 462        if (!setup_phy(dev)) {
 463                axiemac_halt(dev);
 464                return -1;
 465        }
 466
 467        debug("axiemac: Init complete\n");
 468        return 0;
 469}
 470
 471static int axiemac_send(struct eth_device *dev, volatile void *ptr, int len)
 472{
 473        struct axidma_priv *priv = dev->priv;
 474        u32 timeout;
 475
 476        if (len > PKTSIZE_ALIGN)
 477                len = PKTSIZE_ALIGN;
 478
 479        /* Flush packet to main memory to be trasfered by DMA */
 480        flush_cache((u32)ptr, len);
 481
 482        /* Setup Tx BD */
 483        memset(&tx_bd, 0, sizeof(tx_bd));
 484        /* At the end of the ring, link the last BD back to the top */
 485        tx_bd.next = (u32)&tx_bd;
 486        tx_bd.phys = (u32)ptr;
 487        /* Save len */
 488        tx_bd.cntrl = len | XAXIDMA_BD_CTRL_TXSOF_MASK |
 489                                                XAXIDMA_BD_CTRL_TXEOF_MASK;
 490
 491        /* Flush the last BD so DMA core could see the updates */
 492        flush_cache((u32)&tx_bd, sizeof(tx_bd));
 493
 494        if (in_be32(&priv->dmatx->status) & XAXIDMA_HALTED_MASK) {
 495                u32 temp;
 496                out_be32(&priv->dmatx->current, (u32)&tx_bd);
 497                /* Start the hardware */
 498                temp = in_be32(&priv->dmatx->control);
 499                temp |= XAXIDMA_CR_RUNSTOP_MASK;
 500                out_be32(&priv->dmatx->control, temp);
 501        }
 502
 503        /* Start transfer */
 504        out_be32(&priv->dmatx->tail, (u32)&tx_bd);
 505
 506        /* Wait for transmission to complete */
 507        debug("axiemac: Waiting for tx to be done\n");
 508        timeout = 200;
 509        while (timeout && (!in_be32(&priv->dmatx->status) &
 510                        (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) {
 511                timeout--;
 512                udelay(1);
 513        }
 514        if (!timeout) {
 515                printf("%s: Timeout\n", __func__);
 516                return 1;
 517        }
 518
 519        debug("axiemac: Sending complete\n");
 520        return 0;
 521}
 522
 523static int isrxready(struct eth_device *dev)
 524{
 525        u32 status;
 526        struct axidma_priv *priv = dev->priv;
 527
 528        /* Read pending interrupts */
 529        status = in_be32(&priv->dmarx->status);
 530
 531        /* Acknowledge pending interrupts */
 532        out_be32(&priv->dmarx->status, status & XAXIDMA_IRQ_ALL_MASK);
 533
 534        /*
 535         * If Reception done interrupt is asserted, call RX call back function
 536         * to handle the processed BDs and then raise the according flag.
 537         */
 538        if ((status & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))
 539                return 1;
 540
 541        return 0;
 542}
 543
 544static int axiemac_recv(struct eth_device *dev)
 545{
 546        u32 length;
 547        struct axidma_priv *priv = dev->priv;
 548        u32 temp;
 549
 550        /* Wait for an incoming packet */
 551        if (!isrxready(dev))
 552                return 0;
 553
 554        debug("axiemac: RX data ready\n");
 555
 556        /* Disable IRQ for a moment till packet is handled */
 557        temp = in_be32(&priv->dmarx->control);
 558        temp &= ~XAXIDMA_IRQ_ALL_MASK;
 559        out_be32(&priv->dmarx->control, temp);
 560
 561        length = rx_bd.app4 & 0xFFFF; /* max length mask */
 562#ifdef DEBUG
 563        print_buffer(&rxframe, &rxframe[0], 1, length, 16);
 564#endif
 565        /* Pass the received frame up for processing */
 566        if (length)
 567                NetReceive(rxframe, length);
 568
 569#ifdef DEBUG
 570        /* It is useful to clear buffer to be sure that it is consistent */
 571        memset(rxframe, 0, sizeof(rxframe));
 572#endif
 573        /* Setup RxBD */
 574        /* Clear the whole buffer and setup it again - all flags are cleared */
 575        memset(&rx_bd, 0, sizeof(rx_bd));
 576        rx_bd.next = (u32)&rx_bd;
 577        rx_bd.phys = (u32)&rxframe;
 578        rx_bd.cntrl = sizeof(rxframe);
 579
 580        /* Write bd to HW */
 581        flush_cache((u32)&rx_bd, sizeof(rx_bd));
 582
 583        /* It is necessary to flush rxframe because if you don't do it
 584         * then cache will contain previous packet */
 585        flush_cache((u32)&rxframe, sizeof(rxframe));
 586
 587        /* Rx BD is ready - start again */
 588        out_be32(&priv->dmarx->tail, (u32)&rx_bd);
 589
 590        debug("axiemac: RX completed, framelength = %d\n", length);
 591
 592        return length;
 593}
 594
 595static int axiemac_miiphy_read(const char *devname, uchar addr,
 596                                                        uchar reg, ushort *val)
 597{
 598        struct eth_device *dev = eth_get_dev();
 599        u32 ret;
 600
 601        ret = phyread(dev, addr, reg, val);
 602        debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val);
 603        return ret;
 604}
 605
 606static int axiemac_miiphy_write(const char *devname, uchar addr,
 607                                                        uchar reg, ushort val)
 608{
 609        struct eth_device *dev = eth_get_dev();
 610
 611        debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val);
 612        return phywrite(dev, addr, reg, val);
 613}
 614
 615static int axiemac_bus_reset(struct mii_dev *bus)
 616{
 617        debug("axiemac: Bus reset\n");
 618        return 0;
 619}
 620
 621int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
 622                                                        unsigned long dma_addr)
 623{
 624        struct eth_device *dev;
 625        struct axidma_priv *priv;
 626
 627        dev = calloc(1, sizeof(struct eth_device));
 628        if (dev == NULL)
 629                return -1;
 630
 631        dev->priv = calloc(1, sizeof(struct axidma_priv));
 632        if (dev->priv == NULL) {
 633                free(dev);
 634                return -1;
 635        }
 636        priv = dev->priv;
 637
 638        sprintf(dev->name, "aximac.%lx", base_addr);
 639
 640        dev->iobase = base_addr;
 641        priv->dmatx = (struct axidma_reg *)dma_addr;
 642        /* RX channel offset is 0x30 */
 643        priv->dmarx = (struct axidma_reg *)(dma_addr + 0x30);
 644        dev->init = axiemac_init;
 645        dev->halt = axiemac_halt;
 646        dev->send = axiemac_send;
 647        dev->recv = axiemac_recv;
 648        dev->write_hwaddr = axiemac_setup_mac;
 649
 650#ifdef CONFIG_PHY_ADDR
 651        priv->phyaddr = CONFIG_PHY_ADDR;
 652#else
 653        priv->phyaddr = -1;
 654#endif
 655
 656        eth_register(dev);
 657
 658#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
 659        miiphy_register(dev->name, axiemac_miiphy_read, axiemac_miiphy_write);
 660        priv->bus = miiphy_get_dev_by_name(dev->name);
 661        priv->bus->reset = axiemac_bus_reset;
 662#endif
 663        return 1;
 664}
 665