uboot/drivers/net/designware.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2010
   4 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
   5 */
   6
   7/*
   8 * Designware ethernet IP driver for U-Boot
   9 */
  10
  11#include <common.h>
  12#include <clk.h>
  13#include <dm.h>
  14#include <errno.h>
  15#include <miiphy.h>
  16#include <malloc.h>
  17#include <pci.h>
  18#include <reset.h>
  19#include <linux/compiler.h>
  20#include <linux/err.h>
  21#include <linux/kernel.h>
  22#include <asm/io.h>
  23#include <power/regulator.h>
  24#include "designware.h"
  25
  26static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
  27{
  28#ifdef CONFIG_DM_ETH
  29        struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
  30        struct eth_mac_regs *mac_p = priv->mac_regs_p;
  31#else
  32        struct eth_mac_regs *mac_p = bus->priv;
  33#endif
  34        ulong start;
  35        u16 miiaddr;
  36        int timeout = CONFIG_MDIO_TIMEOUT;
  37
  38        miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
  39                  ((reg << MIIREGSHIFT) & MII_REGMSK);
  40
  41        writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
  42
  43        start = get_timer(0);
  44        while (get_timer(start) < timeout) {
  45                if (!(readl(&mac_p->miiaddr) & MII_BUSY))
  46                        return readl(&mac_p->miidata);
  47                udelay(10);
  48        };
  49
  50        return -ETIMEDOUT;
  51}
  52
  53static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
  54                        u16 val)
  55{
  56#ifdef CONFIG_DM_ETH
  57        struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
  58        struct eth_mac_regs *mac_p = priv->mac_regs_p;
  59#else
  60        struct eth_mac_regs *mac_p = bus->priv;
  61#endif
  62        ulong start;
  63        u16 miiaddr;
  64        int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
  65
  66        writel(val, &mac_p->miidata);
  67        miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
  68                  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
  69
  70        writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
  71
  72        start = get_timer(0);
  73        while (get_timer(start) < timeout) {
  74                if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
  75                        ret = 0;
  76                        break;
  77                }
  78                udelay(10);
  79        };
  80
  81        return ret;
  82}
  83
  84#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO)
  85static int dw_mdio_reset(struct mii_dev *bus)
  86{
  87        struct udevice *dev = bus->priv;
  88        struct dw_eth_dev *priv = dev_get_priv(dev);
  89        struct dw_eth_pdata *pdata = dev_get_platdata(dev);
  90        int ret;
  91
  92        if (!dm_gpio_is_valid(&priv->reset_gpio))
  93                return 0;
  94
  95        /* reset the phy */
  96        ret = dm_gpio_set_value(&priv->reset_gpio, 0);
  97        if (ret)
  98                return ret;
  99
 100        udelay(pdata->reset_delays[0]);
 101
 102        ret = dm_gpio_set_value(&priv->reset_gpio, 1);
 103        if (ret)
 104                return ret;
 105
 106        udelay(pdata->reset_delays[1]);
 107
 108        ret = dm_gpio_set_value(&priv->reset_gpio, 0);
 109        if (ret)
 110                return ret;
 111
 112        udelay(pdata->reset_delays[2]);
 113
 114        return 0;
 115}
 116#endif
 117
 118static int dw_mdio_init(const char *name, void *priv)
 119{
 120        struct mii_dev *bus = mdio_alloc();
 121
 122        if (!bus) {
 123                printf("Failed to allocate MDIO bus\n");
 124                return -ENOMEM;
 125        }
 126
 127        bus->read = dw_mdio_read;
 128        bus->write = dw_mdio_write;
 129        snprintf(bus->name, sizeof(bus->name), "%s", name);
 130#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO)
 131        bus->reset = dw_mdio_reset;
 132#endif
 133
 134        bus->priv = priv;
 135
 136        return mdio_register(bus);
 137}
 138
 139static void tx_descs_init(struct dw_eth_dev *priv)
 140{
 141        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 142        struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
 143        char *txbuffs = &priv->txbuffs[0];
 144        struct dmamacdescr *desc_p;
 145        u32 idx;
 146
 147        for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
 148                desc_p = &desc_table_p[idx];
 149                desc_p->dmamac_addr = (ulong)&txbuffs[idx * CONFIG_ETH_BUFSIZE];
 150                desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1];
 151
 152#if defined(CONFIG_DW_ALTDESCRIPTOR)
 153                desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
 154                                DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS |
 155                                DESC_TXSTS_TXCHECKINSCTRL |
 156                                DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
 157
 158                desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
 159                desc_p->dmamac_cntl = 0;
 160                desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
 161#else
 162                desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
 163                desc_p->txrx_status = 0;
 164#endif
 165        }
 166
 167        /* Correcting the last pointer of the chain */
 168        desc_p->dmamac_next = (ulong)&desc_table_p[0];
 169
 170        /* Flush all Tx buffer descriptors at once */
 171        flush_dcache_range((ulong)priv->tx_mac_descrtable,
 172                           (ulong)priv->tx_mac_descrtable +
 173                           sizeof(priv->tx_mac_descrtable));
 174
 175        writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
 176        priv->tx_currdescnum = 0;
 177}
 178
 179static void rx_descs_init(struct dw_eth_dev *priv)
 180{
 181        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 182        struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
 183        char *rxbuffs = &priv->rxbuffs[0];
 184        struct dmamacdescr *desc_p;
 185        u32 idx;
 186
 187        /* Before passing buffers to GMAC we need to make sure zeros
 188         * written there right after "priv" structure allocation were
 189         * flushed into RAM.
 190         * Otherwise there's a chance to get some of them flushed in RAM when
 191         * GMAC is already pushing data to RAM via DMA. This way incoming from
 192         * GMAC data will be corrupted. */
 193        flush_dcache_range((ulong)rxbuffs, (ulong)rxbuffs + RX_TOTAL_BUFSIZE);
 194
 195        for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
 196                desc_p = &desc_table_p[idx];
 197                desc_p->dmamac_addr = (ulong)&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
 198                desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1];
 199
 200                desc_p->dmamac_cntl =
 201                        (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) |
 202                                      DESC_RXCTRL_RXCHAIN;
 203
 204                desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
 205        }
 206
 207        /* Correcting the last pointer of the chain */
 208        desc_p->dmamac_next = (ulong)&desc_table_p[0];
 209
 210        /* Flush all Rx buffer descriptors at once */
 211        flush_dcache_range((ulong)priv->rx_mac_descrtable,
 212                           (ulong)priv->rx_mac_descrtable +
 213                           sizeof(priv->rx_mac_descrtable));
 214
 215        writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
 216        priv->rx_currdescnum = 0;
 217}
 218
 219static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id)
 220{
 221        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 222        u32 macid_lo, macid_hi;
 223
 224        macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
 225                   (mac_id[3] << 24);
 226        macid_hi = mac_id[4] + (mac_id[5] << 8);
 227
 228        writel(macid_hi, &mac_p->macaddr0hi);
 229        writel(macid_lo, &mac_p->macaddr0lo);
 230
 231        return 0;
 232}
 233
 234static int dw_adjust_link(struct dw_eth_dev *priv, struct eth_mac_regs *mac_p,
 235                          struct phy_device *phydev)
 236{
 237        u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN;
 238
 239        if (!phydev->link) {
 240                printf("%s: No link.\n", phydev->dev->name);
 241                return 0;
 242        }
 243
 244        if (phydev->speed != 1000)
 245                conf |= MII_PORTSELECT;
 246        else
 247                conf &= ~MII_PORTSELECT;
 248
 249        if (phydev->speed == 100)
 250                conf |= FES_100;
 251
 252        if (phydev->duplex)
 253                conf |= FULLDPLXMODE;
 254
 255        writel(conf, &mac_p->conf);
 256
 257        printf("Speed: %d, %s duplex%s\n", phydev->speed,
 258               (phydev->duplex) ? "full" : "half",
 259               (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
 260
 261        return 0;
 262}
 263
 264static void _dw_eth_halt(struct dw_eth_dev *priv)
 265{
 266        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 267        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 268
 269        writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf);
 270        writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode);
 271
 272        phy_shutdown(priv->phydev);
 273}
 274
 275int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
 276{
 277        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 278        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 279        unsigned int start;
 280        int ret;
 281
 282        writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
 283
 284        /*
 285         * When a MII PHY is used, we must set the PS bit for the DMA
 286         * reset to succeed.
 287         */
 288        if (priv->phydev->interface == PHY_INTERFACE_MODE_MII)
 289                writel(readl(&mac_p->conf) | MII_PORTSELECT, &mac_p->conf);
 290        else
 291                writel(readl(&mac_p->conf) & ~MII_PORTSELECT, &mac_p->conf);
 292
 293        start = get_timer(0);
 294        while (readl(&dma_p->busmode) & DMAMAC_SRST) {
 295                if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {
 296                        printf("DMA reset timeout\n");
 297                        return -ETIMEDOUT;
 298                }
 299
 300                mdelay(100);
 301        };
 302
 303        /*
 304         * Soft reset above clears HW address registers.
 305         * So we have to set it here once again.
 306         */
 307        _dw_write_hwaddr(priv, enetaddr);
 308
 309        rx_descs_init(priv);
 310        tx_descs_init(priv);
 311
 312        writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);
 313
 314#ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE
 315        writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
 316               &dma_p->opmode);
 317#else
 318        writel(readl(&dma_p->opmode) | FLUSHTXFIFO,
 319               &dma_p->opmode);
 320#endif
 321
 322        writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode);
 323
 324#ifdef CONFIG_DW_AXI_BURST_LEN
 325        writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus);
 326#endif
 327
 328        /* Start up the PHY */
 329        ret = phy_startup(priv->phydev);
 330        if (ret) {
 331                printf("Could not initialize PHY %s\n",
 332                       priv->phydev->dev->name);
 333                return ret;
 334        }
 335
 336        ret = dw_adjust_link(priv, mac_p, priv->phydev);
 337        if (ret)
 338                return ret;
 339
 340        return 0;
 341}
 342
 343int designware_eth_enable(struct dw_eth_dev *priv)
 344{
 345        struct eth_mac_regs *mac_p = priv->mac_regs_p;
 346
 347        if (!priv->phydev->link)
 348                return -EIO;
 349
 350        writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
 351
 352        return 0;
 353}
 354
 355#define ETH_ZLEN        60
 356
 357static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
 358{
 359        struct eth_dma_regs *dma_p = priv->dma_regs_p;
 360        u32 desc_num = priv->tx_currdescnum;
 361        struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
 362        ulong desc_start = (ulong)desc_p;
 363        ulong desc_end = desc_start +
 364                roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
 365        ulong data_start = desc_p->dmamac_addr;
 366        ulong data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
 367        /*
 368         * Strictly we only need to invalidate the "txrx_status" field
 369         * for the following check, but on some platforms we cannot
 370         * invalidate only 4 bytes, so we flush the entire descriptor,
 371         * which is 16 bytes in total. This is safe because the
 372         * individual descriptors in the array are each aligned to
 373         * ARCH_DMA_MINALIGN and padded appropriately.
 374         */
 375        invalidate_dcache_range(desc_start, desc_end);
 376
 377        /* Check if the descriptor is owned by CPU */
 378        if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
 379                printf("CPU not owner of tx frame\n");
 380                return -EPERM;
 381        }
 382
 383        length = max(length, ETH_ZLEN);
 384
 385        memcpy((void *)data_start, packet, length);
 386
 387        /* Flush data to be sent */
 388        flush_dcache_range(data_start, data_end);
 389
 390#if defined(CONFIG_DW_ALTDESCRIPTOR)
 391        desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
 392        desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) &
 393                               DESC_TXCTRL_SIZE1MASK;
 394
 395        desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
 396        desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
 397#else
 398        desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) &
 399                               DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
 400                               DESC_TXCTRL_TXFIRST;
 401
 402        desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
 403#endif
 404
 405        /* Flush modified buffer descriptor */
 406        flush_dcache_range(desc_start, desc_end);
 407
 408        /* Test the wrap-around condition. */
 409        if (++desc_num >= CONFIG_TX_DESCR_NUM)
 410                desc_num = 0;
 411
 412        priv->tx_currdescnum = desc_num;
 413
 414        /* Start the transmission */
 415        writel(POLL_DATA, &dma_p->txpolldemand);
 416
 417        return 0;
 418}
 419
 420static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp)
 421{
 422        u32 status, desc_num = priv->rx_currdescnum;
 423        struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
 424        int length = -EAGAIN;
 425        ulong desc_start = (ulong)desc_p;
 426        ulong desc_end = desc_start +
 427                roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
 428        ulong data_start = desc_p->dmamac_addr;
 429        ulong data_end;
 430
 431        /* Invalidate entire buffer descriptor */
 432        invalidate_dcache_range(desc_start, desc_end);
 433
 434        status = desc_p->txrx_status;
 435
 436        /* Check  if the owner is the CPU */
 437        if (!(status & DESC_RXSTS_OWNBYDMA)) {
 438
 439                length = (status & DESC_RXSTS_FRMLENMSK) >>
 440                         DESC_RXSTS_FRMLENSHFT;
 441
 442                /* Invalidate received data */
 443                data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
 444                invalidate_dcache_range(data_start, data_end);
 445                *packetp = (uchar *)(ulong)desc_p->dmamac_addr;
 446        }
 447
 448        return length;
 449}
 450
 451static int _dw_free_pkt(struct dw_eth_dev *priv)
 452{
 453        u32 desc_num = priv->rx_currdescnum;
 454        struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
 455        ulong desc_start = (ulong)desc_p;
 456        ulong desc_end = desc_start +
 457                roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
 458
 459        /*
 460         * Make the current descriptor valid again and go to
 461         * the next one
 462         */
 463        desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
 464
 465        /* Flush only status field - others weren't changed */
 466        flush_dcache_range(desc_start, desc_end);
 467
 468        /* Test the wrap-around condition. */
 469        if (++desc_num >= CONFIG_RX_DESCR_NUM)
 470                desc_num = 0;
 471        priv->rx_currdescnum = desc_num;
 472
 473        return 0;
 474}
 475
 476static int dw_phy_init(struct dw_eth_dev *priv, void *dev)
 477{
 478        struct phy_device *phydev;
 479        int mask = 0xffffffff, ret;
 480
 481#ifdef CONFIG_PHY_ADDR
 482        mask = 1 << CONFIG_PHY_ADDR;
 483#endif
 484
 485        phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
 486        if (!phydev)
 487                return -ENODEV;
 488
 489        phy_connect_dev(phydev, dev);
 490
 491        phydev->supported &= PHY_GBIT_FEATURES;
 492        if (priv->max_speed) {
 493                ret = phy_set_supported(phydev, priv->max_speed);
 494                if (ret)
 495                        return ret;
 496        }
 497        phydev->advertising = phydev->supported;
 498
 499        priv->phydev = phydev;
 500        phy_config(phydev);
 501
 502        return 0;
 503}
 504
 505#ifndef CONFIG_DM_ETH
 506static int dw_eth_init(struct eth_device *dev, bd_t *bis)
 507{
 508        int ret;
 509
 510        ret = designware_eth_init(dev->priv, dev->enetaddr);
 511        if (!ret)
 512                ret = designware_eth_enable(dev->priv);
 513
 514        return ret;
 515}
 516
 517static int dw_eth_send(struct eth_device *dev, void *packet, int length)
 518{
 519        return _dw_eth_send(dev->priv, packet, length);
 520}
 521
 522static int dw_eth_recv(struct eth_device *dev)
 523{
 524        uchar *packet;
 525        int length;
 526
 527        length = _dw_eth_recv(dev->priv, &packet);
 528        if (length == -EAGAIN)
 529                return 0;
 530        net_process_received_packet(packet, length);
 531
 532        _dw_free_pkt(dev->priv);
 533
 534        return 0;
 535}
 536
 537static void dw_eth_halt(struct eth_device *dev)
 538{
 539        return _dw_eth_halt(dev->priv);
 540}
 541
 542static int dw_write_hwaddr(struct eth_device *dev)
 543{
 544        return _dw_write_hwaddr(dev->priv, dev->enetaddr);
 545}
 546
 547int designware_initialize(ulong base_addr, u32 interface)
 548{
 549        struct eth_device *dev;
 550        struct dw_eth_dev *priv;
 551
 552        dev = (struct eth_device *) malloc(sizeof(struct eth_device));
 553        if (!dev)
 554                return -ENOMEM;
 555
 556        /*
 557         * Since the priv structure contains the descriptors which need a strict
 558         * buswidth alignment, memalign is used to allocate memory
 559         */
 560        priv = (struct dw_eth_dev *) memalign(ARCH_DMA_MINALIGN,
 561                                              sizeof(struct dw_eth_dev));
 562        if (!priv) {
 563                free(dev);
 564                return -ENOMEM;
 565        }
 566
 567        if ((phys_addr_t)priv + sizeof(*priv) > (1ULL << 32)) {
 568                printf("designware: buffers are outside DMA memory\n");
 569                return -EINVAL;
 570        }
 571
 572        memset(dev, 0, sizeof(struct eth_device));
 573        memset(priv, 0, sizeof(struct dw_eth_dev));
 574
 575        sprintf(dev->name, "dwmac.%lx", base_addr);
 576        dev->iobase = (int)base_addr;
 577        dev->priv = priv;
 578
 579        priv->dev = dev;
 580        priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
 581        priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
 582                        DW_DMA_BASE_OFFSET);
 583
 584        dev->init = dw_eth_init;
 585        dev->send = dw_eth_send;
 586        dev->recv = dw_eth_recv;
 587        dev->halt = dw_eth_halt;
 588        dev->write_hwaddr = dw_write_hwaddr;
 589
 590        eth_register(dev);
 591
 592        priv->interface = interface;
 593
 594        dw_mdio_init(dev->name, priv->mac_regs_p);
 595        priv->bus = miiphy_get_dev_by_name(dev->name);
 596
 597        return dw_phy_init(priv, dev);
 598}
 599#endif
 600
 601#ifdef CONFIG_DM_ETH
 602static int designware_eth_start(struct udevice *dev)
 603{
 604        struct eth_pdata *pdata = dev_get_platdata(dev);
 605        struct dw_eth_dev *priv = dev_get_priv(dev);
 606        int ret;
 607
 608        ret = designware_eth_init(priv, pdata->enetaddr);
 609        if (ret)
 610                return ret;
 611        ret = designware_eth_enable(priv);
 612        if (ret)
 613                return ret;
 614
 615        return 0;
 616}
 617
 618int designware_eth_send(struct udevice *dev, void *packet, int length)
 619{
 620        struct dw_eth_dev *priv = dev_get_priv(dev);
 621
 622        return _dw_eth_send(priv, packet, length);
 623}
 624
 625int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp)
 626{
 627        struct dw_eth_dev *priv = dev_get_priv(dev);
 628
 629        return _dw_eth_recv(priv, packetp);
 630}
 631
 632int designware_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
 633{
 634        struct dw_eth_dev *priv = dev_get_priv(dev);
 635
 636        return _dw_free_pkt(priv);
 637}
 638
 639void designware_eth_stop(struct udevice *dev)
 640{
 641        struct dw_eth_dev *priv = dev_get_priv(dev);
 642
 643        return _dw_eth_halt(priv);
 644}
 645
 646int designware_eth_write_hwaddr(struct udevice *dev)
 647{
 648        struct eth_pdata *pdata = dev_get_platdata(dev);
 649        struct dw_eth_dev *priv = dev_get_priv(dev);
 650
 651        return _dw_write_hwaddr(priv, pdata->enetaddr);
 652}
 653
 654static int designware_eth_bind(struct udevice *dev)
 655{
 656#ifdef CONFIG_DM_PCI
 657        static int num_cards;
 658        char name[20];
 659
 660        /* Create a unique device name for PCI type devices */
 661        if (device_is_on_pci_bus(dev)) {
 662                sprintf(name, "eth_designware#%u", num_cards++);
 663                device_set_name(dev, name);
 664        }
 665#endif
 666
 667        return 0;
 668}
 669
 670int designware_eth_probe(struct udevice *dev)
 671{
 672        struct eth_pdata *pdata = dev_get_platdata(dev);
 673        struct dw_eth_dev *priv = dev_get_priv(dev);
 674        u32 iobase = pdata->iobase;
 675        ulong ioaddr;
 676        int ret;
 677        struct reset_ctl_bulk reset_bulk;
 678#ifdef CONFIG_CLK
 679        int i, err, clock_nb;
 680
 681        priv->clock_count = 0;
 682        clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
 683        if (clock_nb > 0) {
 684                priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
 685                                            GFP_KERNEL);
 686                if (!priv->clocks)
 687                        return -ENOMEM;
 688
 689                for (i = 0; i < clock_nb; i++) {
 690                        err = clk_get_by_index(dev, i, &priv->clocks[i]);
 691                        if (err < 0)
 692                                break;
 693
 694                        err = clk_enable(&priv->clocks[i]);
 695                        if (err && err != -ENOSYS && err != -ENOTSUPP) {
 696                                pr_err("failed to enable clock %d\n", i);
 697                                clk_free(&priv->clocks[i]);
 698                                goto clk_err;
 699                        }
 700                        priv->clock_count++;
 701                }
 702        } else if (clock_nb != -ENOENT) {
 703                pr_err("failed to get clock phandle(%d)\n", clock_nb);
 704                return clock_nb;
 705        }
 706#endif
 707
 708#if defined(CONFIG_DM_REGULATOR)
 709        struct udevice *phy_supply;
 710
 711        ret = device_get_supply_regulator(dev, "phy-supply",
 712                                          &phy_supply);
 713        if (ret) {
 714                debug("%s: No phy supply\n", dev->name);
 715        } else {
 716                ret = regulator_set_enable(phy_supply, true);
 717                if (ret) {
 718                        puts("Error enabling phy supply\n");
 719                        return ret;
 720                }
 721        }
 722#endif
 723
 724        ret = reset_get_bulk(dev, &reset_bulk);
 725        if (ret)
 726                dev_warn(dev, "Can't get reset: %d\n", ret);
 727        else
 728                reset_deassert_bulk(&reset_bulk);
 729
 730#ifdef CONFIG_DM_PCI
 731        /*
 732         * If we are on PCI bus, either directly attached to a PCI root port,
 733         * or via a PCI bridge, fill in platdata before we probe the hardware.
 734         */
 735        if (device_is_on_pci_bus(dev)) {
 736                dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase);
 737                iobase &= PCI_BASE_ADDRESS_MEM_MASK;
 738                iobase = dm_pci_mem_to_phys(dev, iobase);
 739
 740                pdata->iobase = iobase;
 741                pdata->phy_interface = PHY_INTERFACE_MODE_RMII;
 742        }
 743#endif
 744
 745        debug("%s, iobase=%x, priv=%p\n", __func__, iobase, priv);
 746        ioaddr = iobase;
 747        priv->mac_regs_p = (struct eth_mac_regs *)ioaddr;
 748        priv->dma_regs_p = (struct eth_dma_regs *)(ioaddr + DW_DMA_BASE_OFFSET);
 749        priv->interface = pdata->phy_interface;
 750        priv->max_speed = pdata->max_speed;
 751
 752        dw_mdio_init(dev->name, dev);
 753        priv->bus = miiphy_get_dev_by_name(dev->name);
 754
 755        ret = dw_phy_init(priv, dev);
 756        debug("%s, ret=%d\n", __func__, ret);
 757
 758        return ret;
 759
 760#ifdef CONFIG_CLK
 761clk_err:
 762        ret = clk_release_all(priv->clocks, priv->clock_count);
 763        if (ret)
 764                pr_err("failed to disable all clocks\n");
 765
 766        return err;
 767#endif
 768}
 769
 770static int designware_eth_remove(struct udevice *dev)
 771{
 772        struct dw_eth_dev *priv = dev_get_priv(dev);
 773
 774        free(priv->phydev);
 775        mdio_unregister(priv->bus);
 776        mdio_free(priv->bus);
 777
 778#ifdef CONFIG_CLK
 779        return clk_release_all(priv->clocks, priv->clock_count);
 780#else
 781        return 0;
 782#endif
 783}
 784
 785const struct eth_ops designware_eth_ops = {
 786        .start                  = designware_eth_start,
 787        .send                   = designware_eth_send,
 788        .recv                   = designware_eth_recv,
 789        .free_pkt               = designware_eth_free_pkt,
 790        .stop                   = designware_eth_stop,
 791        .write_hwaddr           = designware_eth_write_hwaddr,
 792};
 793
 794int designware_eth_ofdata_to_platdata(struct udevice *dev)
 795{
 796        struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
 797#ifdef CONFIG_DM_GPIO
 798        struct dw_eth_dev *priv = dev_get_priv(dev);
 799#endif
 800        struct eth_pdata *pdata = &dw_pdata->eth_pdata;
 801        const char *phy_mode;
 802#ifdef CONFIG_DM_GPIO
 803        int reset_flags = GPIOD_IS_OUT;
 804#endif
 805        int ret = 0;
 806
 807        pdata->iobase = dev_read_addr(dev);
 808        pdata->phy_interface = -1;
 809        phy_mode = dev_read_string(dev, "phy-mode");
 810        if (phy_mode)
 811                pdata->phy_interface = phy_get_interface_by_name(phy_mode);
 812        if (pdata->phy_interface == -1) {
 813                debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
 814                return -EINVAL;
 815        }
 816
 817        pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
 818
 819#ifdef CONFIG_DM_GPIO
 820        if (dev_read_bool(dev, "snps,reset-active-low"))
 821                reset_flags |= GPIOD_ACTIVE_LOW;
 822
 823        ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
 824                &priv->reset_gpio, reset_flags);
 825        if (ret == 0) {
 826                ret = dev_read_u32_array(dev, "snps,reset-delays-us",
 827                                         dw_pdata->reset_delays, 3);
 828        } else if (ret == -ENOENT) {
 829                ret = 0;
 830        }
 831#endif
 832
 833        return ret;
 834}
 835
 836static const struct udevice_id designware_eth_ids[] = {
 837        { .compatible = "allwinner,sun7i-a20-gmac" },
 838        { .compatible = "altr,socfpga-stmmac" },
 839        { .compatible = "amlogic,meson6-dwmac" },
 840        { .compatible = "amlogic,meson-gx-dwmac" },
 841        { .compatible = "st,stm32-dwmac" },
 842        { }
 843};
 844
 845U_BOOT_DRIVER(eth_designware) = {
 846        .name   = "eth_designware",
 847        .id     = UCLASS_ETH,
 848        .of_match = designware_eth_ids,
 849        .ofdata_to_platdata = designware_eth_ofdata_to_platdata,
 850        .bind   = designware_eth_bind,
 851        .probe  = designware_eth_probe,
 852        .remove = designware_eth_remove,
 853        .ops    = &designware_eth_ops,
 854        .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
 855        .platdata_auto_alloc_size = sizeof(struct dw_eth_pdata),
 856        .flags = DM_FLAG_ALLOC_PRIV_DMA,
 857};
 858
 859static struct pci_device_id supported[] = {
 860        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_EMAC) },
 861        { }
 862};
 863
 864U_BOOT_PCI_DEVICE(eth_designware, supported);
 865#endif
 866