uboot/drivers/net/altera_tse.c
<<
>>
Prefs
   1/*
   2 * Altera 10/100/1000 triple speed ethernet mac driver
   3 *
   4 * Copyright (C) 2008 Altera Corporation.
   5 * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#include <common.h>
  12#include <cpu_func.h>
  13#include <dm.h>
  14#include <errno.h>
  15#include <fdt_support.h>
  16#include <log.h>
  17#include <memalign.h>
  18#include <miiphy.h>
  19#include <net.h>
  20#include <asm/cache.h>
  21#include <asm/global_data.h>
  22#include <linux/dma-mapping.h>
  23#include <asm/io.h>
  24#include "altera_tse.h"
  25
  26DECLARE_GLOBAL_DATA_PTR;
  27
  28static inline void alt_sgdma_construct_descriptor(
  29        struct alt_sgdma_descriptor *desc,
  30        struct alt_sgdma_descriptor *next,
  31        void *read_addr,
  32        void *write_addr,
  33        u16 length_or_eop,
  34        int generate_eop,
  35        int read_fixed,
  36        int write_fixed_or_sop)
  37{
  38        u8 val;
  39
  40        /*
  41         * Mark the "next" descriptor as "not" owned by hardware. This prevents
  42         * The SGDMA controller from continuing to process the chain.
  43         */
  44        next->descriptor_control = next->descriptor_control &
  45                ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
  46
  47        memset(desc, 0, sizeof(struct alt_sgdma_descriptor));
  48        desc->source = virt_to_phys(read_addr);
  49        desc->destination = virt_to_phys(write_addr);
  50        desc->next = virt_to_phys(next);
  51        desc->bytes_to_transfer = length_or_eop;
  52
  53        /*
  54         * Set the descriptor control block as follows:
  55         * - Set "owned by hardware" bit
  56         * - Optionally set "generate EOP" bit
  57         * - Optionally set the "read from fixed address" bit
  58         * - Optionally set the "write to fixed address bit (which serves
  59         *   serves as a "generate SOP" control bit in memory-to-stream mode).
  60         * - Set the 4-bit atlantic channel, if specified
  61         *
  62         * Note this step is performed after all other descriptor information
  63         * has been filled out so that, if the controller already happens to be
  64         * pointing at this descriptor, it will not run (via the "owned by
  65         * hardware" bit) until all other descriptor has been set up.
  66         */
  67        val = ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
  68        if (generate_eop)
  69                val |= ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK;
  70        if (read_fixed)
  71                val |= ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK;
  72        if (write_fixed_or_sop)
  73                val |= ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK;
  74        desc->descriptor_control = val;
  75}
  76
  77static int alt_sgdma_wait_transfer(struct alt_sgdma_registers *regs)
  78{
  79        int status;
  80        ulong ctime;
  81
  82        /* Wait for the descriptor (chain) to complete */
  83        ctime = get_timer(0);
  84        while (1) {
  85                status = readl(&regs->status);
  86                if (!(status & ALT_SGDMA_STATUS_BUSY_MSK))
  87                        break;
  88                if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) {
  89                        status = -ETIMEDOUT;
  90                        debug("sgdma timeout\n");
  91                        break;
  92                }
  93        }
  94
  95        /* Clear Run */
  96        writel(0, &regs->control);
  97        /* Clear status */
  98        writel(0xff, &regs->status);
  99
 100        return status;
 101}
 102
 103static int alt_sgdma_start_transfer(struct alt_sgdma_registers *regs,
 104                                    struct alt_sgdma_descriptor *desc)
 105{
 106        u32 val;
 107
 108        /* Point the controller at the descriptor */
 109        writel(virt_to_phys(desc), &regs->next_descriptor_pointer);
 110
 111        /*
 112         * Set up SGDMA controller to:
 113         * - Disable interrupt generation
 114         * - Run once a valid descriptor is written to controller
 115         * - Stop on an error with any particular descriptor
 116         */
 117        val = ALT_SGDMA_CONTROL_RUN_MSK | ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK;
 118        writel(val, &regs->control);
 119
 120        return 0;
 121}
 122
 123static void tse_adjust_link(struct altera_tse_priv *priv,
 124                            struct phy_device *phydev)
 125{
 126        struct alt_tse_mac *mac_dev = priv->mac_dev;
 127        u32 refvar;
 128
 129        if (!phydev->link) {
 130                debug("%s: No link.\n", phydev->dev->name);
 131                return;
 132        }
 133
 134        refvar = readl(&mac_dev->command_config);
 135
 136        if (phydev->duplex)
 137                refvar |= ALTERA_TSE_CMD_HD_ENA_MSK;
 138        else
 139                refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK;
 140
 141        switch (phydev->speed) {
 142        case 1000:
 143                refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK;
 144                refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
 145                break;
 146        case 100:
 147                refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
 148                refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
 149                break;
 150        case 10:
 151                refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
 152                refvar |= ALTERA_TSE_CMD_ENA_10_MSK;
 153                break;
 154        }
 155        writel(refvar, &mac_dev->command_config);
 156}
 157
 158static int altera_tse_send_sgdma(struct udevice *dev, void *packet, int length)
 159{
 160        struct altera_tse_priv *priv = dev_get_priv(dev);
 161        struct alt_sgdma_descriptor *tx_desc = priv->tx_desc;
 162
 163        alt_sgdma_construct_descriptor(
 164                tx_desc,
 165                tx_desc + 1,
 166                packet, /* read addr */
 167                NULL,   /* write addr */
 168                length, /* length or EOP ,will change for each tx */
 169                1,      /* gen eop */
 170                0,      /* read fixed */
 171                1       /* write fixed or sop */
 172                );
 173
 174        /* send the packet */
 175        alt_sgdma_start_transfer(priv->sgdma_tx, tx_desc);
 176        alt_sgdma_wait_transfer(priv->sgdma_tx);
 177        debug("sent %d bytes\n", tx_desc->actual_bytes_transferred);
 178
 179        return tx_desc->actual_bytes_transferred;
 180}
 181
 182static int altera_tse_recv_sgdma(struct udevice *dev, int flags,
 183                                 uchar **packetp)
 184{
 185        struct altera_tse_priv *priv = dev_get_priv(dev);
 186        struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
 187        int packet_length;
 188
 189        if (rx_desc->descriptor_status &
 190            ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {
 191                alt_sgdma_wait_transfer(priv->sgdma_rx);
 192                packet_length = rx_desc->actual_bytes_transferred;
 193                debug("recv %d bytes\n", packet_length);
 194                *packetp = priv->rx_buf;
 195
 196                return packet_length;
 197        }
 198
 199        return -EAGAIN;
 200}
 201
 202static int altera_tse_free_pkt_sgdma(struct udevice *dev, uchar *packet,
 203                                     int length)
 204{
 205        struct altera_tse_priv *priv = dev_get_priv(dev);
 206        struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
 207
 208        alt_sgdma_construct_descriptor(
 209                rx_desc,
 210                rx_desc + 1,
 211                NULL,   /* read addr */
 212                priv->rx_buf, /* write addr */
 213                0,      /* length or EOP */
 214                0,      /* gen eop */
 215                0,      /* read fixed */
 216                0       /* write fixed or sop */
 217                );
 218
 219        /* setup the sgdma */
 220        alt_sgdma_start_transfer(priv->sgdma_rx, rx_desc);
 221        debug("recv setup\n");
 222
 223        return 0;
 224}
 225
 226static void altera_tse_stop_mac(struct altera_tse_priv *priv)
 227{
 228        struct alt_tse_mac *mac_dev = priv->mac_dev;
 229        u32 status;
 230        ulong ctime;
 231
 232        /* reset the mac */
 233        writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config);
 234        ctime = get_timer(0);
 235        while (1) {
 236                status = readl(&mac_dev->command_config);
 237                if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK))
 238                        break;
 239                if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) {
 240                        debug("Reset mac timeout\n");
 241                        break;
 242                }
 243        }
 244}
 245
 246static void altera_tse_stop_sgdma(struct udevice *dev)
 247{
 248        struct altera_tse_priv *priv = dev_get_priv(dev);
 249        struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;
 250        struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
 251        struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
 252        int ret;
 253
 254        /* clear rx desc & wait for sgdma to complete */
 255        rx_desc->descriptor_control = 0;
 256        writel(0, &rx_sgdma->control);
 257        ret = alt_sgdma_wait_transfer(rx_sgdma);
 258        if (ret == -ETIMEDOUT)
 259                writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
 260                       &rx_sgdma->control);
 261
 262        writel(0, &tx_sgdma->control);
 263        ret = alt_sgdma_wait_transfer(tx_sgdma);
 264        if (ret == -ETIMEDOUT)
 265                writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
 266                       &tx_sgdma->control);
 267}
 268
 269static void msgdma_reset(struct msgdma_csr *csr)
 270{
 271        u32 status;
 272        ulong ctime;
 273
 274        /* Reset mSGDMA */
 275        writel(MSGDMA_CSR_STAT_MASK, &csr->status);
 276        writel(MSGDMA_CSR_CTL_RESET, &csr->control);
 277        ctime = get_timer(0);
 278        while (1) {
 279                status = readl(&csr->status);
 280                if (!(status & MSGDMA_CSR_STAT_RESETTING))
 281                        break;
 282                if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) {
 283                        debug("Reset msgdma timeout\n");
 284                        break;
 285                }
 286        }
 287        /* Clear status */
 288        writel(MSGDMA_CSR_STAT_MASK, &csr->status);
 289}
 290
 291static u32 msgdma_wait(struct msgdma_csr *csr)
 292{
 293        u32 status;
 294        ulong ctime;
 295
 296        /* Wait for the descriptor to complete */
 297        ctime = get_timer(0);
 298        while (1) {
 299                status = readl(&csr->status);
 300                if (!(status & MSGDMA_CSR_STAT_BUSY))
 301                        break;
 302                if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) {
 303                        debug("sgdma timeout\n");
 304                        break;
 305                }
 306        }
 307        /* Clear status */
 308        writel(MSGDMA_CSR_STAT_MASK, &csr->status);
 309
 310        return status;
 311}
 312
 313static int altera_tse_send_msgdma(struct udevice *dev, void *packet,
 314                                  int length)
 315{
 316        struct altera_tse_priv *priv = dev_get_priv(dev);
 317        struct msgdma_extended_desc *desc = priv->tx_desc;
 318        u32 tx_buf = virt_to_phys(packet);
 319        u32 status;
 320
 321        writel(tx_buf, &desc->read_addr_lo);
 322        writel(0, &desc->read_addr_hi);
 323        writel(0, &desc->write_addr_lo);
 324        writel(0, &desc->write_addr_hi);
 325        writel(length, &desc->len);
 326        writel(0, &desc->burst_seq_num);
 327        writel(MSGDMA_DESC_TX_STRIDE, &desc->stride);
 328        writel(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control);
 329        status = msgdma_wait(priv->sgdma_tx);
 330        debug("sent %d bytes, status %08x\n", length, status);
 331
 332        return 0;
 333}
 334
 335static int altera_tse_recv_msgdma(struct udevice *dev, int flags,
 336                                  uchar **packetp)
 337{
 338        struct altera_tse_priv *priv = dev_get_priv(dev);
 339        struct msgdma_csr *csr = priv->sgdma_rx;
 340        struct msgdma_response *resp = priv->rx_resp;
 341        u32 level, length, status;
 342
 343        level = readl(&csr->resp_fill_level);
 344        if (level & 0xffff) {
 345                length = readl(&resp->bytes_transferred);
 346                status = readl(&resp->status);
 347                debug("recv %d bytes, status %08x\n", length, status);
 348                *packetp = priv->rx_buf;
 349
 350                return length;
 351        }
 352
 353        return -EAGAIN;
 354}
 355
 356static int altera_tse_free_pkt_msgdma(struct udevice *dev, uchar *packet,
 357                                      int length)
 358{
 359        struct altera_tse_priv *priv = dev_get_priv(dev);
 360        struct msgdma_extended_desc *desc = priv->rx_desc;
 361        u32 rx_buf = virt_to_phys(priv->rx_buf);
 362
 363        writel(0, &desc->read_addr_lo);
 364        writel(0, &desc->read_addr_hi);
 365        writel(rx_buf, &desc->write_addr_lo);
 366        writel(0, &desc->write_addr_hi);
 367        writel(PKTSIZE_ALIGN, &desc->len);
 368        writel(0, &desc->burst_seq_num);
 369        writel(MSGDMA_DESC_RX_STRIDE, &desc->stride);
 370        writel(MSGDMA_DESC_CTL_RX_SINGLE, &desc->control);
 371        debug("recv setup\n");
 372
 373        return 0;
 374}
 375
 376static void altera_tse_stop_msgdma(struct udevice *dev)
 377{
 378        struct altera_tse_priv *priv = dev_get_priv(dev);
 379
 380        msgdma_reset(priv->sgdma_rx);
 381        msgdma_reset(priv->sgdma_tx);
 382}
 383
 384static int tse_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 385{
 386        struct altera_tse_priv *priv = bus->priv;
 387        struct alt_tse_mac *mac_dev = priv->mac_dev;
 388        u32 value;
 389
 390        /* set mdio address */
 391        writel(addr, &mac_dev->mdio_phy1_addr);
 392        /* get the data */
 393        value = readl(&mac_dev->mdio_phy1[reg]);
 394
 395        return value & 0xffff;
 396}
 397
 398static int tse_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 399                          u16 val)
 400{
 401        struct altera_tse_priv *priv = bus->priv;
 402        struct alt_tse_mac *mac_dev = priv->mac_dev;
 403
 404        /* set mdio address */
 405        writel(addr, &mac_dev->mdio_phy1_addr);
 406        /* set the data */
 407        writel(val, &mac_dev->mdio_phy1[reg]);
 408
 409        return 0;
 410}
 411
 412static int tse_mdio_init(const char *name, struct altera_tse_priv *priv)
 413{
 414        struct mii_dev *bus = mdio_alloc();
 415
 416        if (!bus) {
 417                printf("Failed to allocate MDIO bus\n");
 418                return -ENOMEM;
 419        }
 420
 421        bus->read = tse_mdio_read;
 422        bus->write = tse_mdio_write;
 423        snprintf(bus->name, sizeof(bus->name), "%s", name);
 424
 425        bus->priv = (void *)priv;
 426
 427        return mdio_register(bus);
 428}
 429
 430static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
 431{
 432        struct phy_device *phydev;
 433        unsigned int mask = 0xffffffff;
 434
 435        if (priv->phyaddr)
 436                mask = 1 << priv->phyaddr;
 437
 438        phydev = phy_find_by_mask(priv->bus, mask);
 439        if (!phydev)
 440                return -ENODEV;
 441
 442        phy_connect_dev(phydev, dev, priv->interface);
 443
 444        phydev->supported &= PHY_GBIT_FEATURES;
 445        phydev->advertising = phydev->supported;
 446
 447        priv->phydev = phydev;
 448        phy_config(phydev);
 449
 450        return 0;
 451}
 452
 453static int altera_tse_write_hwaddr(struct udevice *dev)
 454{
 455        struct altera_tse_priv *priv = dev_get_priv(dev);
 456        struct alt_tse_mac *mac_dev = priv->mac_dev;
 457        struct eth_pdata *pdata = dev_get_plat(dev);
 458        u8 *hwaddr = pdata->enetaddr;
 459        u32 mac_lo, mac_hi;
 460
 461        mac_lo = (hwaddr[3] << 24) | (hwaddr[2] << 16) |
 462                (hwaddr[1] << 8) | hwaddr[0];
 463        mac_hi = (hwaddr[5] << 8) | hwaddr[4];
 464        debug("Set MAC address to 0x%04x%08x\n", mac_hi, mac_lo);
 465
 466        writel(mac_lo, &mac_dev->mac_addr_0);
 467        writel(mac_hi, &mac_dev->mac_addr_1);
 468        writel(mac_lo, &mac_dev->supp_mac_addr_0_0);
 469        writel(mac_hi, &mac_dev->supp_mac_addr_0_1);
 470        writel(mac_lo, &mac_dev->supp_mac_addr_1_0);
 471        writel(mac_hi, &mac_dev->supp_mac_addr_1_1);
 472        writel(mac_lo, &mac_dev->supp_mac_addr_2_0);
 473        writel(mac_hi, &mac_dev->supp_mac_addr_2_1);
 474        writel(mac_lo, &mac_dev->supp_mac_addr_3_0);
 475        writel(mac_hi, &mac_dev->supp_mac_addr_3_1);
 476
 477        return 0;
 478}
 479
 480static int altera_tse_send(struct udevice *dev, void *packet, int length)
 481{
 482        struct altera_tse_priv *priv = dev_get_priv(dev);
 483        unsigned long tx_buf = (unsigned long)packet;
 484
 485        flush_dcache_range(tx_buf, tx_buf + length);
 486
 487        return priv->ops->send(dev, packet, length);
 488}
 489
 490static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp)
 491{
 492        struct altera_tse_priv *priv = dev_get_priv(dev);
 493
 494        return priv->ops->recv(dev, flags, packetp);
 495}
 496
 497static int altera_tse_free_pkt(struct udevice *dev, uchar *packet,
 498                               int length)
 499{
 500        struct altera_tse_priv *priv = dev_get_priv(dev);
 501        unsigned long rx_buf = (unsigned long)priv->rx_buf;
 502
 503        invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN);
 504
 505        return priv->ops->free_pkt(dev, packet, length);
 506}
 507
 508static void altera_tse_stop(struct udevice *dev)
 509{
 510        struct altera_tse_priv *priv = dev_get_priv(dev);
 511
 512        priv->ops->stop(dev);
 513        altera_tse_stop_mac(priv);
 514}
 515
 516static int altera_tse_start(struct udevice *dev)
 517{
 518        struct altera_tse_priv *priv = dev_get_priv(dev);
 519        struct alt_tse_mac *mac_dev = priv->mac_dev;
 520        u32 val;
 521        int ret;
 522
 523        /* need to create sgdma */
 524        debug("Configuring rx desc\n");
 525        altera_tse_free_pkt(dev, priv->rx_buf, PKTSIZE_ALIGN);
 526        /* start TSE */
 527        debug("Configuring TSE Mac\n");
 528        /* Initialize MAC registers */
 529        writel(PKTSIZE_ALIGN, &mac_dev->max_frame_length);
 530        writel(priv->rx_fifo_depth - 16, &mac_dev->rx_sel_empty_threshold);
 531        writel(0, &mac_dev->rx_sel_full_threshold);
 532        writel(priv->tx_fifo_depth - 16, &mac_dev->tx_sel_empty_threshold);
 533        writel(0, &mac_dev->tx_sel_full_threshold);
 534        writel(8, &mac_dev->rx_almost_empty_threshold);
 535        writel(8, &mac_dev->rx_almost_full_threshold);
 536        writel(8, &mac_dev->tx_almost_empty_threshold);
 537        writel(3, &mac_dev->tx_almost_full_threshold);
 538
 539        /* NO Shift */
 540        writel(0, &mac_dev->rx_cmd_stat);
 541        writel(0, &mac_dev->tx_cmd_stat);
 542
 543        /* enable MAC */
 544        val = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK;
 545        writel(val, &mac_dev->command_config);
 546
 547        /* Start up the PHY */
 548        ret = phy_startup(priv->phydev);
 549        if (ret) {
 550                debug("Could not initialize PHY %s\n",
 551                      priv->phydev->dev->name);
 552                return ret;
 553        }
 554
 555        tse_adjust_link(priv, priv->phydev);
 556
 557        if (!priv->phydev->link)
 558                return -EIO;
 559
 560        return 0;
 561}
 562
 563static const struct tse_ops tse_sgdma_ops = {
 564        .send           = altera_tse_send_sgdma,
 565        .recv           = altera_tse_recv_sgdma,
 566        .free_pkt       = altera_tse_free_pkt_sgdma,
 567        .stop           = altera_tse_stop_sgdma,
 568};
 569
 570static const struct tse_ops tse_msgdma_ops = {
 571        .send           = altera_tse_send_msgdma,
 572        .recv           = altera_tse_recv_msgdma,
 573        .free_pkt       = altera_tse_free_pkt_msgdma,
 574        .stop           = altera_tse_stop_msgdma,
 575};
 576
 577static int altera_tse_probe(struct udevice *dev)
 578{
 579        struct eth_pdata *pdata = dev_get_plat(dev);
 580        struct altera_tse_priv *priv = dev_get_priv(dev);
 581        void *blob = (void *)gd->fdt_blob;
 582        int node = dev_of_offset(dev);
 583        const char *list, *end;
 584        const fdt32_t *cell;
 585        void *base, *desc_mem = NULL;
 586        unsigned long addr, size;
 587        int parent, addrc, sizec;
 588        int len, idx;
 589        int ret;
 590
 591        priv->dma_type = dev_get_driver_data(dev);
 592        if (priv->dma_type == ALT_SGDMA)
 593                priv->ops = &tse_sgdma_ops;
 594        else
 595                priv->ops = &tse_msgdma_ops;
 596        /*
 597         * decode regs. there are multiple reg tuples, and they need to
 598         * match with reg-names.
 599         */
 600        parent = fdt_parent_offset(blob, node);
 601        fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
 602        list = fdt_getprop(blob, node, "reg-names", &len);
 603        if (!list)
 604                return -ENOENT;
 605        end = list + len;
 606        cell = fdt_getprop(blob, node, "reg", &len);
 607        if (!cell)
 608                return -ENOENT;
 609        idx = 0;
 610        while (list < end) {
 611                addr = fdt_translate_address((void *)blob,
 612                                             node, cell + idx);
 613                size = fdt_addr_to_cpu(cell[idx + addrc]);
 614                base = map_physmem(addr, size, MAP_NOCACHE);
 615                len = strlen(list);
 616                if (strcmp(list, "control_port") == 0)
 617                        priv->mac_dev = base;
 618                else if (strcmp(list, "rx_csr") == 0)
 619                        priv->sgdma_rx = base;
 620                else if (strcmp(list, "rx_desc") == 0)
 621                        priv->rx_desc = base;
 622                else if (strcmp(list, "rx_resp") == 0)
 623                        priv->rx_resp = base;
 624                else if (strcmp(list, "tx_csr") == 0)
 625                        priv->sgdma_tx = base;
 626                else if (strcmp(list, "tx_desc") == 0)
 627                        priv->tx_desc = base;
 628                else if (strcmp(list, "s1") == 0)
 629                        desc_mem = base;
 630                idx += addrc + sizec;
 631                list += (len + 1);
 632        }
 633        /* decode fifo depth */
 634        priv->rx_fifo_depth = fdtdec_get_int(blob, node,
 635                "rx-fifo-depth", 0);
 636        priv->tx_fifo_depth = fdtdec_get_int(blob, node,
 637                "tx-fifo-depth", 0);
 638        /* decode phy */
 639        addr = fdtdec_get_int(blob, node,
 640                              "phy-handle", 0);
 641        addr = fdt_node_offset_by_phandle(blob, addr);
 642        priv->phyaddr = fdtdec_get_int(blob, addr,
 643                "reg", 0);
 644        /* init desc */
 645        if (priv->dma_type == ALT_SGDMA) {
 646                len = sizeof(struct alt_sgdma_descriptor) * 4;
 647                if (!desc_mem) {
 648                        desc_mem = dma_alloc_coherent(len, &addr);
 649                        if (!desc_mem)
 650                                return -ENOMEM;
 651                }
 652                memset(desc_mem, 0, len);
 653                priv->tx_desc = desc_mem;
 654                priv->rx_desc = priv->tx_desc +
 655                        2 * sizeof(struct alt_sgdma_descriptor);
 656        }
 657        /* allocate recv packet buffer */
 658        priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN);
 659        if (!priv->rx_buf)
 660                return -ENOMEM;
 661
 662        /* stop controller */
 663        debug("Reset TSE & SGDMAs\n");
 664        altera_tse_stop(dev);
 665
 666        /* start the phy */
 667        priv->interface = pdata->phy_interface;
 668        tse_mdio_init(dev->name, priv);
 669        priv->bus = miiphy_get_dev_by_name(dev->name);
 670
 671        ret = tse_phy_init(priv, dev);
 672
 673        return ret;
 674}
 675
 676static int altera_tse_of_to_plat(struct udevice *dev)
 677{
 678        struct eth_pdata *pdata = dev_get_plat(dev);
 679
 680        pdata->phy_interface = dev_read_phy_mode(dev);
 681        if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
 682                return -EINVAL;
 683
 684        return 0;
 685}
 686
 687static const struct eth_ops altera_tse_ops = {
 688        .start          = altera_tse_start,
 689        .send           = altera_tse_send,
 690        .recv           = altera_tse_recv,
 691        .free_pkt       = altera_tse_free_pkt,
 692        .stop           = altera_tse_stop,
 693        .write_hwaddr   = altera_tse_write_hwaddr,
 694};
 695
 696static const struct udevice_id altera_tse_ids[] = {
 697        { .compatible = "altr,tse-msgdma-1.0", .data = ALT_MSGDMA },
 698        { .compatible = "altr,tse-1.0", .data = ALT_SGDMA },
 699        {}
 700};
 701
 702U_BOOT_DRIVER(altera_tse) = {
 703        .name   = "altera_tse",
 704        .id     = UCLASS_ETH,
 705        .of_match = altera_tse_ids,
 706        .ops    = &altera_tse_ops,
 707        .of_to_plat = altera_tse_of_to_plat,
 708        .plat_auto      = sizeof(struct eth_pdata),
 709        .priv_auto      = sizeof(struct altera_tse_priv),
 710        .probe  = altera_tse_probe,
 711};
 712