uboot/drivers/net/mvgbe.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2009
   4 * Marvell Semiconductor <www.marvell.com>
   5 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
   6 *
   7 * (C) Copyright 2003
   8 * Ingo Assmus <ingo.assmus@keymile.com>
   9 *
  10 * based on - Driver for MV64360X ethernet ports
  11 * Copyright (C) 2002 rabeeh@galileo.co.il
  12 */
  13
  14#include <common.h>
  15#include <dm.h>
  16#include <net.h>
  17#include <malloc.h>
  18#include <miiphy.h>
  19#include <wait_bit.h>
  20#include <asm/io.h>
  21#include <linux/errno.h>
  22#include <asm/types.h>
  23#include <asm/system.h>
  24#include <asm/byteorder.h>
  25#include <asm/arch/cpu.h>
  26
  27#if defined(CONFIG_KIRKWOOD)
  28#include <asm/arch/soc.h>
  29#elif defined(CONFIG_ORION5X)
  30#include <asm/arch/orion5x.h>
  31#endif
  32
  33#include "mvgbe.h"
  34
  35DECLARE_GLOBAL_DATA_PTR;
  36
  37#ifndef CONFIG_MVGBE_PORTS
  38# define CONFIG_MVGBE_PORTS {0, 0}
  39#endif
  40
  41#define MV_PHY_ADR_REQUEST 0xee
  42#define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi)
  43
  44#if defined(CONFIG_PHYLIB) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
  45static int smi_wait_ready(struct mvgbe_device *dmvgbe)
  46{
  47        int ret;
  48
  49        ret = wait_for_bit_le32(&MVGBE_SMI_REG, MVGBE_PHY_SMI_BUSY_MASK, false,
  50                                MVGBE_PHY_SMI_TIMEOUT_MS, false);
  51        if (ret) {
  52                printf("Error: SMI busy timeout\n");
  53                return ret;
  54        }
  55
  56        return 0;
  57}
  58
  59static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
  60                             int devad, int reg_ofs)
  61{
  62        struct mvgbe_registers *regs = dmvgbe->regs;
  63        u32 smi_reg;
  64        u32 timeout;
  65        u16 data = 0;
  66
  67        /* Phyadr read request */
  68        if (phy_adr == MV_PHY_ADR_REQUEST &&
  69                        reg_ofs == MV_PHY_ADR_REQUEST) {
  70                /* */
  71                data = (u16) (MVGBE_REG_RD(regs->phyadr) & PHYADR_MASK);
  72                return data;
  73        }
  74        /* check parameters */
  75        if (phy_adr > PHYADR_MASK) {
  76                printf("Err..(%s) Invalid PHY address %d\n",
  77                        __func__, phy_adr);
  78                return -EFAULT;
  79        }
  80        if (reg_ofs > PHYREG_MASK) {
  81                printf("Err..(%s) Invalid register offset %d\n",
  82                        __func__, reg_ofs);
  83                return -EFAULT;
  84        }
  85
  86        /* wait till the SMI is not busy */
  87        if (smi_wait_ready(dmvgbe) < 0)
  88                return -EFAULT;
  89
  90        /* fill the phy address and regiser offset and read opcode */
  91        smi_reg = (phy_adr << MVGBE_PHY_SMI_DEV_ADDR_OFFS)
  92                | (reg_ofs << MVGBE_SMI_REG_ADDR_OFFS)
  93                | MVGBE_PHY_SMI_OPCODE_READ;
  94
  95        /* write the smi register */
  96        MVGBE_REG_WR(MVGBE_SMI_REG, smi_reg);
  97
  98        /*wait till read value is ready */
  99        timeout = MVGBE_PHY_SMI_TIMEOUT;
 100
 101        do {
 102                /* read smi register */
 103                smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
 104                if (timeout-- == 0) {
 105                        printf("Err..(%s) SMI read ready timeout\n",
 106                                __func__);
 107                        return -EFAULT;
 108                }
 109        } while (!(smi_reg & MVGBE_PHY_SMI_READ_VALID_MASK));
 110
 111        /* Wait for the data to update in the SMI register */
 112        for (timeout = 0; timeout < MVGBE_PHY_SMI_TIMEOUT; timeout++)
 113                ;
 114
 115        data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK);
 116
 117        debug("%s:(adr %d, off %d) value= %04x\n", __func__, phy_adr, reg_ofs,
 118              data);
 119
 120        return data;
 121}
 122
 123/*
 124 * smi_reg_read - miiphy_read callback function.
 125 *
 126 * Returns 16bit phy register value, or -EFAULT on error
 127 */
 128static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
 129                        int reg_ofs)
 130{
 131#ifdef CONFIG_DM_ETH
 132        struct mvgbe_device *dmvgbe = bus->priv;
 133#else
 134        struct eth_device *dev = eth_get_dev_by_name(bus->name);
 135        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 136#endif
 137
 138        return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
 139}
 140
 141static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
 142                              int devad, int reg_ofs, u16 data)
 143{
 144        struct mvgbe_registers *regs = dmvgbe->regs;
 145        u32 smi_reg;
 146
 147        /* Phyadr write request*/
 148        if (phy_adr == MV_PHY_ADR_REQUEST &&
 149                        reg_ofs == MV_PHY_ADR_REQUEST) {
 150                MVGBE_REG_WR(regs->phyadr, data);
 151                return 0;
 152        }
 153
 154        /* check parameters */
 155        if (phy_adr > PHYADR_MASK) {
 156                printf("Err..(%s) Invalid phy address\n", __func__);
 157                return -EINVAL;
 158        }
 159        if (reg_ofs > PHYREG_MASK) {
 160                printf("Err..(%s) Invalid register offset\n", __func__);
 161                return -EFAULT;
 162        }
 163
 164        /* wait till the SMI is not busy */
 165        if (smi_wait_ready(dmvgbe) < 0)
 166                return -EFAULT;
 167
 168        /* fill the phy addr and reg offset and write opcode and data */
 169        smi_reg = (data << MVGBE_PHY_SMI_DATA_OFFS);
 170        smi_reg |= (phy_adr << MVGBE_PHY_SMI_DEV_ADDR_OFFS)
 171                | (reg_ofs << MVGBE_SMI_REG_ADDR_OFFS);
 172        smi_reg &= ~MVGBE_PHY_SMI_OPCODE_READ;
 173
 174        /* write the smi register */
 175        MVGBE_REG_WR(MVGBE_SMI_REG, smi_reg);
 176
 177        return 0;
 178}
 179
 180/*
 181 * smi_reg_write - miiphy_write callback function.
 182 *
 183 * Returns 0 if write succeed, -EFAULT on error
 184 */
 185static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
 186                         int reg_ofs, u16 data)
 187{
 188#ifdef CONFIG_DM_ETH
 189        struct mvgbe_device *dmvgbe = bus->priv;
 190#else
 191        struct eth_device *dev = eth_get_dev_by_name(bus->name);
 192        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 193#endif
 194
 195        return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
 196}
 197#endif
 198
 199/* Stop and checks all queues */
 200static void stop_queue(u32 * qreg)
 201{
 202        u32 reg_data;
 203
 204        reg_data = readl(qreg);
 205
 206        if (reg_data & 0xFF) {
 207                /* Issue stop command for active channels only */
 208                writel((reg_data << 8), qreg);
 209
 210                /* Wait for all queue activity to terminate. */
 211                do {
 212                        /*
 213                         * Check port cause register that all queues
 214                         * are stopped
 215                         */
 216                        reg_data = readl(qreg);
 217                }
 218                while (reg_data & 0xFF);
 219        }
 220}
 221
 222/*
 223 * set_access_control - Config address decode parameters for Ethernet unit
 224 *
 225 * This function configures the address decode parameters for the Gigabit
 226 * Ethernet Controller according the given parameters struct.
 227 *
 228 * @regs        Register struct pointer.
 229 * @param       Address decode parameter struct.
 230 */
 231static void set_access_control(struct mvgbe_registers *regs,
 232                                struct mvgbe_winparam *param)
 233{
 234        u32 access_prot_reg;
 235
 236        /* Set access control register */
 237        access_prot_reg = MVGBE_REG_RD(regs->epap);
 238        /* clear window permission */
 239        access_prot_reg &= (~(3 << (param->win * 2)));
 240        access_prot_reg |= (param->access_ctrl << (param->win * 2));
 241        MVGBE_REG_WR(regs->epap, access_prot_reg);
 242
 243        /* Set window Size reg (SR) */
 244        MVGBE_REG_WR(regs->barsz[param->win].size,
 245                        (((param->size / 0x10000) - 1) << 16));
 246
 247        /* Set window Base address reg (BA) */
 248        MVGBE_REG_WR(regs->barsz[param->win].bar,
 249                        (param->target | param->attrib | param->base_addr));
 250        /* High address remap reg (HARR) */
 251        if (param->win < 4)
 252                MVGBE_REG_WR(regs->ha_remap[param->win], param->high_addr);
 253
 254        /* Base address enable reg (BARER) */
 255        if (param->enable == 1)
 256                MVGBE_REG_BITS_RESET(regs->bare, (1 << param->win));
 257        else
 258                MVGBE_REG_BITS_SET(regs->bare, (1 << param->win));
 259}
 260
 261static void set_dram_access(struct mvgbe_registers *regs)
 262{
 263        struct mvgbe_winparam win_param;
 264        int i;
 265
 266        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 267                /* Set access parameters for DRAM bank i */
 268                win_param.win = i;      /* Use Ethernet window i */
 269                /* Window target - DDR */
 270                win_param.target = MVGBE_TARGET_DRAM;
 271                /* Enable full access */
 272                win_param.access_ctrl = EWIN_ACCESS_FULL;
 273                win_param.high_addr = 0;
 274                /* Get bank base and size */
 275                win_param.base_addr = gd->bd->bi_dram[i].start;
 276                win_param.size = gd->bd->bi_dram[i].size;
 277                if (win_param.size == 0)
 278                        win_param.enable = 0;
 279                else
 280                        win_param.enable = 1;   /* Enable the access */
 281
 282                /* Enable DRAM bank */
 283                switch (i) {
 284                case 0:
 285                        win_param.attrib = EBAR_DRAM_CS0;
 286                        break;
 287                case 1:
 288                        win_param.attrib = EBAR_DRAM_CS1;
 289                        break;
 290                case 2:
 291                        win_param.attrib = EBAR_DRAM_CS2;
 292                        break;
 293                case 3:
 294                        win_param.attrib = EBAR_DRAM_CS3;
 295                        break;
 296                default:
 297                        /* invalid bank, disable access */
 298                        win_param.enable = 0;
 299                        win_param.attrib = 0;
 300                        break;
 301                }
 302                /* Set the access control for address window(EPAPR) RD/WR */
 303                set_access_control(regs, &win_param);
 304        }
 305}
 306
 307/*
 308 * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
 309 *
 310 * Go through all the DA filter tables (Unicast, Special Multicast & Other
 311 * Multicast) and set each entry to 0.
 312 */
 313static void port_init_mac_tables(struct mvgbe_registers *regs)
 314{
 315        int table_index;
 316
 317        /* Clear DA filter unicast table (Ex_dFUT) */
 318        for (table_index = 0; table_index < 4; ++table_index)
 319                MVGBE_REG_WR(regs->dfut[table_index], 0);
 320
 321        for (table_index = 0; table_index < 64; ++table_index) {
 322                /* Clear DA filter special multicast table (Ex_dFSMT) */
 323                MVGBE_REG_WR(regs->dfsmt[table_index], 0);
 324                /* Clear DA filter other multicast table (Ex_dFOMT) */
 325                MVGBE_REG_WR(regs->dfomt[table_index], 0);
 326        }
 327}
 328
 329/*
 330 * port_uc_addr - This function Set the port unicast address table
 331 *
 332 * This function locates the proper entry in the Unicast table for the
 333 * specified MAC nibble and sets its properties according to function
 334 * parameters.
 335 * This function add/removes MAC addresses from the port unicast address
 336 * table.
 337 *
 338 * @uc_nibble   Unicast MAC Address last nibble.
 339 * @option      0 = Add, 1 = remove address.
 340 *
 341 * RETURN: 1 if output succeeded. 0 if option parameter is invalid.
 342 */
 343static int port_uc_addr(struct mvgbe_registers *regs, u8 uc_nibble,
 344                        int option)
 345{
 346        u32 unicast_reg;
 347        u32 tbl_offset;
 348        u32 reg_offset;
 349
 350        /* Locate the Unicast table entry */
 351        uc_nibble = (0xf & uc_nibble);
 352        /* Register offset from unicast table base */
 353        tbl_offset = (uc_nibble / 4);
 354        /* Entry offset within the above register */
 355        reg_offset = uc_nibble % 4;
 356
 357        switch (option) {
 358        case REJECT_MAC_ADDR:
 359                /*
 360                 * Clear accepts frame bit at specified unicast
 361                 * DA table entry
 362                 */
 363                unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]);
 364                unicast_reg &= (0xFF << (8 * reg_offset));
 365                MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg);
 366                break;
 367        case ACCEPT_MAC_ADDR:
 368                /* Set accepts frame bit at unicast DA filter table entry */
 369                unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]);
 370                unicast_reg &= (0xFF << (8 * reg_offset));
 371                unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset));
 372                MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg);
 373                break;
 374        default:
 375                return 0;
 376        }
 377        return 1;
 378}
 379
 380/*
 381 * port_uc_addr_set - This function Set the port Unicast address.
 382 */
 383static void port_uc_addr_set(struct mvgbe_device *dmvgbe, u8 *p_addr)
 384{
 385        struct mvgbe_registers *regs = dmvgbe->regs;
 386        u32 mac_h;
 387        u32 mac_l;
 388
 389        mac_l = (p_addr[4] << 8) | (p_addr[5]);
 390        mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
 391                (p_addr[3] << 0);
 392
 393        MVGBE_REG_WR(regs->macal, mac_l);
 394        MVGBE_REG_WR(regs->macah, mac_h);
 395
 396        /* Accept frames of this address */
 397        port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR);
 398}
 399
 400/*
 401 * mvgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
 402 */
 403static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
 404{
 405        struct mvgbe_rxdesc *p_rx_desc;
 406        int i;
 407
 408        /* initialize the Rx descriptors ring */
 409        p_rx_desc = dmvgbe->p_rxdesc;
 410        for (i = 0; i < RINGSZ; i++) {
 411                p_rx_desc->cmd_sts =
 412                        MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_EN_INTERRUPT;
 413                p_rx_desc->buf_size = PKTSIZE_ALIGN;
 414                p_rx_desc->byte_cnt = 0;
 415                p_rx_desc->buf_ptr = dmvgbe->p_rxbuf + i * PKTSIZE_ALIGN;
 416                if (i == (RINGSZ - 1))
 417                        p_rx_desc->nxtdesc_p = dmvgbe->p_rxdesc;
 418                else {
 419                        p_rx_desc->nxtdesc_p = (struct mvgbe_rxdesc *)
 420                                ((u32) p_rx_desc + MV_RXQ_DESC_ALIGNED_SIZE);
 421                        p_rx_desc = p_rx_desc->nxtdesc_p;
 422                }
 423        }
 424        dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
 425}
 426
 427static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr,
 428                        const char *name)
 429{
 430        struct mvgbe_registers *regs = dmvgbe->regs;
 431#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) &&  \
 432        !defined(CONFIG_PHYLIB) &&                       \
 433        !defined(CONFIG_DM_ETH) &&                       \
 434        defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
 435        int i;
 436#endif
 437        /* setup RX rings */
 438        mvgbe_init_rx_desc_ring(dmvgbe);
 439
 440        /* Clear the ethernet port interrupts */
 441        MVGBE_REG_WR(regs->ic, 0);
 442        MVGBE_REG_WR(regs->ice, 0);
 443        /* Unmask RX buffer and TX end interrupt */
 444        MVGBE_REG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
 445        /* Unmask phy and link status changes interrupts */
 446        MVGBE_REG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);
 447
 448        set_dram_access(regs);
 449        port_init_mac_tables(regs);
 450        port_uc_addr_set(dmvgbe, enetaddr);
 451
 452        /* Assign port configuration and command. */
 453        MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
 454        MVGBE_REG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE);
 455        MVGBE_REG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE);
 456
 457        /* Assign port SDMA configuration */
 458        MVGBE_REG_WR(regs->sdc, PORT_SDMA_CFG_VALUE);
 459        MVGBE_REG_WR(regs->tqx[0].qxttbc, QTKNBKT_DEF_VAL);
 460        MVGBE_REG_WR(regs->tqx[0].tqxtbc,
 461                (QMTBS_DEF_VAL << 16) | QTKNRT_DEF_VAL);
 462        /* Turn off the port/RXUQ bandwidth limitation */
 463        MVGBE_REG_WR(regs->pmtu, 0);
 464
 465        /* Set maximum receive buffer to 9700 bytes */
 466        MVGBE_REG_WR(regs->psc0, MVGBE_MAX_RX_PACKET_9700BYTE
 467                        | (MVGBE_REG_RD(regs->psc0) & MRU_MASK));
 468
 469        /* Enable port initially */
 470        MVGBE_REG_BITS_SET(regs->psc0, MVGBE_SERIAL_PORT_EN);
 471
 472        /*
 473         * Set ethernet MTU for leaky bucket mechanism to 0 - this will
 474         * disable the leaky bucket mechanism .
 475         */
 476        MVGBE_REG_WR(regs->pmtu, 0);
 477
 478        /* Assignment of Rx CRDB of given RXUQ */
 479        MVGBE_REG_WR(regs->rxcdp[RXUQ], (u32) dmvgbe->p_rxdesc_curr);
 480        /* ensure previous write is done before enabling Rx DMA */
 481        isb();
 482        /* Enable port Rx. */
 483        MVGBE_REG_WR(regs->rqc, (1 << RXUQ));
 484
 485#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
 486        !defined(CONFIG_PHYLIB) && \
 487        !defined(CONFIG_DM_ETH) && \
 488        defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
 489        /* Wait up to 5s for the link status */
 490        for (i = 0; i < 5; i++) {
 491                u16 phyadr;
 492
 493                miiphy_read(name, MV_PHY_ADR_REQUEST,
 494                                MV_PHY_ADR_REQUEST, &phyadr);
 495                /* Return if we get link up */
 496                if (miiphy_link(name, phyadr))
 497                        return 0;
 498                udelay(1000000);
 499        }
 500
 501        printf("No link on %s\n", name);
 502        return -1;
 503#endif
 504        return 0;
 505}
 506
 507#ifndef CONFIG_DM_ETH
 508static int mvgbe_init(struct eth_device *dev)
 509{
 510        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 511
 512        return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr, dmvgbe->dev.name);
 513}
 514#endif
 515
 516static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
 517{
 518        struct mvgbe_registers *regs = dmvgbe->regs;
 519
 520        /* Disable all gigE address decoder */
 521        MVGBE_REG_WR(regs->bare, 0x3f);
 522
 523        stop_queue(&regs->tqc);
 524        stop_queue(&regs->rqc);
 525
 526        /* Disable port */
 527        MVGBE_REG_BITS_RESET(regs->psc0, MVGBE_SERIAL_PORT_EN);
 528        /* Set port is not reset */
 529        MVGBE_REG_BITS_RESET(regs->psc1, 1 << 4);
 530#ifdef CONFIG_SYS_MII_MODE
 531        /* Set MMI interface up */
 532        MVGBE_REG_BITS_RESET(regs->psc1, 1 << 3);
 533#endif
 534        /* Disable & mask ethernet port interrupts */
 535        MVGBE_REG_WR(regs->ic, 0);
 536        MVGBE_REG_WR(regs->ice, 0);
 537        MVGBE_REG_WR(regs->pim, 0);
 538        MVGBE_REG_WR(regs->peim, 0);
 539}
 540
 541#ifndef CONFIG_DM_ETH
 542static int mvgbe_halt(struct eth_device *dev)
 543{
 544        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 545
 546        __mvgbe_halt(dmvgbe);
 547
 548        return 0;
 549}
 550#endif
 551
 552#ifdef CONFIG_DM_ETH
 553static int mvgbe_write_hwaddr(struct udevice *dev)
 554{
 555        struct eth_pdata *pdata = dev_get_platdata(dev);
 556
 557        port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
 558
 559        return 0;
 560}
 561#else
 562static int mvgbe_write_hwaddr(struct eth_device *dev)
 563{
 564        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 565
 566        /* Programs net device MAC address after initialization */
 567        port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
 568        return 0;
 569}
 570#endif
 571
 572static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
 573                        int datasize)
 574{
 575        struct mvgbe_registers *regs = dmvgbe->regs;
 576        struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc;
 577        void *p = (void *)dataptr;
 578        u32 cmd_sts;
 579        u32 txuq0_reg_addr;
 580
 581        /* Copy buffer if it's misaligned */
 582        if ((u32) dataptr & 0x07) {
 583                if (datasize > PKTSIZE_ALIGN) {
 584                        printf("Non-aligned data too large (%d)\n",
 585                                        datasize);
 586                        return -1;
 587                }
 588
 589                memcpy(dmvgbe->p_aligned_txbuf, p, datasize);
 590                p = dmvgbe->p_aligned_txbuf;
 591        }
 592
 593        p_txdesc->cmd_sts = MVGBE_ZERO_PADDING | MVGBE_GEN_CRC;
 594        p_txdesc->cmd_sts |= MVGBE_TX_FIRST_DESC | MVGBE_TX_LAST_DESC;
 595        p_txdesc->cmd_sts |= MVGBE_BUFFER_OWNED_BY_DMA;
 596        p_txdesc->cmd_sts |= MVGBE_TX_EN_INTERRUPT;
 597        p_txdesc->buf_ptr = (u8 *) p;
 598        p_txdesc->byte_cnt = datasize;
 599
 600        /* Set this tc desc as zeroth TXUQ */
 601        txuq0_reg_addr = (u32)&regs->tcqdp[TXUQ];
 602        writel((u32) p_txdesc, txuq0_reg_addr);
 603
 604        /* ensure tx desc writes above are performed before we start Tx DMA */
 605        isb();
 606
 607        /* Apply send command using zeroth TXUQ */
 608        MVGBE_REG_WR(regs->tqc, (1 << TXUQ));
 609
 610        /*
 611         * wait for packet xmit completion
 612         */
 613        cmd_sts = readl(&p_txdesc->cmd_sts);
 614        while (cmd_sts & MVGBE_BUFFER_OWNED_BY_DMA) {
 615                /* return fail if error is detected */
 616                if ((cmd_sts & (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME)) ==
 617                                (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME) &&
 618                                cmd_sts & (MVGBE_UR_ERROR | MVGBE_RL_ERROR)) {
 619                        printf("Err..(%s) in xmit packet\n", __func__);
 620                        return -1;
 621                }
 622                cmd_sts = readl(&p_txdesc->cmd_sts);
 623        };
 624        return 0;
 625}
 626
 627#ifndef CONFIG_DM_ETH
 628static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
 629{
 630        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 631
 632        return __mvgbe_send(dmvgbe, dataptr, datasize);
 633}
 634#endif
 635
 636static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
 637{
 638        struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr;
 639        u32 cmd_sts;
 640        u32 timeout = 0;
 641        u32 rxdesc_curr_addr;
 642        unsigned char *data;
 643        int rx_bytes = 0;
 644
 645        *packetp = NULL;
 646
 647        /* wait untill rx packet available or timeout */
 648        do {
 649                if (timeout < MVGBE_PHY_SMI_TIMEOUT)
 650                        timeout++;
 651                else {
 652                        debug("%s time out...\n", __func__);
 653                        return -1;
 654                }
 655        } while (readl(&p_rxdesc_curr->cmd_sts) & MVGBE_BUFFER_OWNED_BY_DMA);
 656
 657        if (p_rxdesc_curr->byte_cnt != 0) {
 658                debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n",
 659                        __func__, (u32) p_rxdesc_curr->byte_cnt,
 660                        (u32) p_rxdesc_curr->buf_ptr,
 661                        (u32) p_rxdesc_curr->cmd_sts);
 662        }
 663
 664        /*
 665         * In case received a packet without first/last bits on
 666         * OR the error summary bit is on,
 667         * the packets needs to be dropeed.
 668         */
 669        cmd_sts = readl(&p_rxdesc_curr->cmd_sts);
 670
 671        if ((cmd_sts &
 672                (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC))
 673                != (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC)) {
 674
 675                printf("Err..(%s) Dropping packet spread on"
 676                        " multiple descriptors\n", __func__);
 677
 678        } else if (cmd_sts & MVGBE_ERROR_SUMMARY) {
 679
 680                printf("Err..(%s) Dropping packet with errors\n",
 681                        __func__);
 682
 683        } else {
 684                /* !!! call higher layer processing */
 685                debug("%s: Sending Received packet to"
 686                      " upper layer (net_process_received_packet)\n",
 687                      __func__);
 688
 689                data = (p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET);
 690                rx_bytes = (int)(p_rxdesc_curr->byte_cnt -
 691                                                  RX_BUF_OFFSET);
 692
 693                *packetp = data;
 694        }
 695        /*
 696         * free these descriptors and point next in the ring
 697         */
 698        p_rxdesc_curr->cmd_sts =
 699                MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_EN_INTERRUPT;
 700        p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
 701        p_rxdesc_curr->byte_cnt = 0;
 702
 703        rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr;
 704        writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr);
 705
 706        return rx_bytes;
 707}
 708
 709#ifndef CONFIG_DM_ETH
 710static int mvgbe_recv(struct eth_device *dev)
 711{
 712        struct mvgbe_device *dmvgbe = to_mvgbe(dev);
 713        uchar *packet;
 714        int ret;
 715
 716        ret = __mvgbe_recv(dmvgbe, &packet);
 717        if (ret < 0)
 718                return ret;
 719
 720        net_process_received_packet(packet, ret);
 721
 722        return 0;
 723}
 724#endif
 725
 726#if defined(CONFIG_PHYLIB) || defined(CONFIG_DM_ETH)
 727#if defined(CONFIG_DM_ETH)
 728static struct phy_device *__mvgbe_phy_init(struct udevice *dev,
 729                                           struct mii_dev *bus,
 730                                           phy_interface_t phy_interface,
 731                                           int phyid)
 732#else
 733static struct phy_device *__mvgbe_phy_init(struct eth_device *dev,
 734                                           struct mii_dev *bus,
 735                                           phy_interface_t phy_interface,
 736                                           int phyid)
 737#endif
 738{
 739        struct phy_device *phydev;
 740
 741        /* Set phy address of the port */
 742        miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
 743                     phyid);
 744
 745        phydev = phy_connect(bus, phyid, dev, phy_interface);
 746        if (!phydev) {
 747                printf("phy_connect failed\n");
 748                return NULL;
 749        }
 750
 751        phy_config(phydev);
 752        phy_startup(phydev);
 753
 754        return phydev;
 755}
 756#endif /* CONFIG_PHYLIB || CONFIG_DM_ETH */
 757
 758#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
 759int mvgbe_phylib_init(struct eth_device *dev, int phyid)
 760{
 761        struct mii_dev *bus;
 762        struct phy_device *phydev;
 763        int ret;
 764
 765        bus = mdio_alloc();
 766        if (!bus) {
 767                printf("mdio_alloc failed\n");
 768                return -ENOMEM;
 769        }
 770        bus->read = smi_reg_read;
 771        bus->write = smi_reg_write;
 772        strcpy(bus->name, dev->name);
 773
 774        ret = mdio_register(bus);
 775        if (ret) {
 776                printf("mdio_register failed\n");
 777                free(bus);
 778                return -ENOMEM;
 779        }
 780
 781        phydev = __mvgbe_phy_init(dev, bus, PHY_INTERFACE_MODE_RGMII, phyid);
 782        if (!phydev)
 783                return -ENODEV;
 784
 785        return 0;
 786}
 787#endif
 788
 789static int mvgbe_alloc_buffers(struct mvgbe_device *dmvgbe)
 790{
 791        dmvgbe->p_rxdesc = memalign(PKTALIGN,
 792                                    MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
 793        if (!dmvgbe->p_rxdesc)
 794                goto error1;
 795
 796        dmvgbe->p_rxbuf = memalign(PKTALIGN,
 797                                   RINGSZ * PKTSIZE_ALIGN + 1);
 798        if (!dmvgbe->p_rxbuf)
 799                goto error2;
 800
 801        dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
 802        if (!dmvgbe->p_aligned_txbuf)
 803                goto error3;
 804
 805        dmvgbe->p_txdesc = memalign(PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
 806        if (!dmvgbe->p_txdesc)
 807                goto error4;
 808
 809        return 0;
 810
 811error4:
 812        free(dmvgbe->p_aligned_txbuf);
 813error3:
 814        free(dmvgbe->p_rxbuf);
 815error2:
 816        free(dmvgbe->p_rxdesc);
 817error1:
 818        return -ENOMEM;
 819}
 820
 821#ifndef CONFIG_DM_ETH
 822int mvgbe_initialize(bd_t *bis)
 823{
 824        struct mvgbe_device *dmvgbe;
 825        struct eth_device *dev;
 826        int devnum;
 827        int ret;
 828        u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
 829
 830        for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
 831                /*skip if port is configured not to use */
 832                if (used_ports[devnum] == 0)
 833                        continue;
 834
 835                dmvgbe = malloc(sizeof(struct mvgbe_device));
 836                if (!dmvgbe)
 837                        return -ENOMEM;
 838
 839                memset(dmvgbe, 0, sizeof(struct mvgbe_device));
 840                ret = mvgbe_alloc_buffers(dmvgbe);
 841                if (ret) {
 842                        printf("Err.. %s Failed to allocate memory\n",
 843                                __func__);
 844                        free(dmvgbe);
 845                        return ret;
 846                }
 847
 848                dev = &dmvgbe->dev;
 849
 850                /* must be less than sizeof(dev->name) */
 851                sprintf(dev->name, "egiga%d", devnum);
 852
 853                switch (devnum) {
 854                case 0:
 855                        dmvgbe->regs = (void *)MVGBE0_BASE;
 856                        break;
 857#if defined(MVGBE1_BASE)
 858                case 1:
 859                        dmvgbe->regs = (void *)MVGBE1_BASE;
 860                        break;
 861#endif
 862                default:        /* this should never happen */
 863                        printf("Err..(%s) Invalid device number %d\n",
 864                                __func__, devnum);
 865                        return -1;
 866                }
 867
 868                dev->init = (void *)mvgbe_init;
 869                dev->halt = (void *)mvgbe_halt;
 870                dev->send = (void *)mvgbe_send;
 871                dev->recv = (void *)mvgbe_recv;
 872                dev->write_hwaddr = (void *)mvgbe_write_hwaddr;
 873
 874                eth_register(dev);
 875
 876#if defined(CONFIG_PHYLIB)
 877                mvgbe_phylib_init(dev, PHY_BASE_ADR + devnum);
 878#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 879                int retval;
 880                struct mii_dev *mdiodev = mdio_alloc();
 881                if (!mdiodev)
 882                        return -ENOMEM;
 883                strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
 884                mdiodev->read = smi_reg_read;
 885                mdiodev->write = smi_reg_write;
 886
 887                retval = mdio_register(mdiodev);
 888                if (retval < 0)
 889                        return retval;
 890                /* Set phy address of the port */
 891                miiphy_write(dev->name, MV_PHY_ADR_REQUEST,
 892                                MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
 893#endif
 894        }
 895        return 0;
 896}
 897#endif
 898
 899#ifdef CONFIG_DM_ETH
 900static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
 901{
 902        return dmvgbe->phyaddr > PHY_MAX_ADDR;
 903}
 904
 905static int mvgbe_start(struct udevice *dev)
 906{
 907        struct eth_pdata *pdata = dev_get_platdata(dev);
 908        struct mvgbe_device *dmvgbe = dev_get_priv(dev);
 909        int ret;
 910
 911        ret = __mvgbe_init(dmvgbe, pdata->enetaddr, dev->name);
 912        if (ret)
 913                return ret;
 914
 915        if (!mvgbe_port_is_fixed_link(dmvgbe)) {
 916                dmvgbe->phydev = __mvgbe_phy_init(dev, dmvgbe->bus,
 917                                                  dmvgbe->phy_interface,
 918                                                  dmvgbe->phyaddr);
 919                if (!dmvgbe->phydev)
 920                        return -ENODEV;
 921        }
 922
 923        return 0;
 924}
 925
 926static int mvgbe_send(struct udevice *dev, void *packet, int length)
 927{
 928        struct mvgbe_device *dmvgbe = dev_get_priv(dev);
 929
 930        return __mvgbe_send(dmvgbe, packet, length);
 931}
 932
 933static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
 934{
 935        struct mvgbe_device *dmvgbe = dev_get_priv(dev);
 936
 937        return __mvgbe_recv(dmvgbe, packetp);
 938}
 939
 940static void mvgbe_stop(struct udevice *dev)
 941{
 942        struct mvgbe_device *dmvgbe = dev_get_priv(dev);
 943
 944        __mvgbe_halt(dmvgbe);
 945}
 946
 947static int mvgbe_probe(struct udevice *dev)
 948{
 949        struct eth_pdata *pdata = dev_get_platdata(dev);
 950        struct mvgbe_device *dmvgbe = dev_get_priv(dev);
 951        struct mii_dev *bus;
 952        int ret;
 953
 954        ret = mvgbe_alloc_buffers(dmvgbe);
 955        if (ret)
 956                return ret;
 957
 958        dmvgbe->regs = (void __iomem *)pdata->iobase;
 959
 960        bus  = mdio_alloc();
 961        if (!bus) {
 962                printf("Failed to allocate MDIO bus\n");
 963                return -ENOMEM;
 964        }
 965
 966        bus->read = smi_reg_read;
 967        bus->write = smi_reg_write;
 968        snprintf(bus->name, sizeof(bus->name), dev->name);
 969        bus->priv = dmvgbe;
 970        dmvgbe->bus = bus;
 971
 972        ret = mdio_register(bus);
 973        if (ret < 0)
 974                return ret;
 975
 976        return 0;
 977}
 978
 979static const struct eth_ops mvgbe_ops = {
 980        .start          = mvgbe_start,
 981        .send           = mvgbe_send,
 982        .recv           = mvgbe_recv,
 983        .stop           = mvgbe_stop,
 984        .write_hwaddr   = mvgbe_write_hwaddr,
 985};
 986
 987static int mvgbe_ofdata_to_platdata(struct udevice *dev)
 988{
 989        struct eth_pdata *pdata = dev_get_platdata(dev);
 990        struct mvgbe_device *dmvgbe = dev_get_priv(dev);
 991        void *blob = (void *)gd->fdt_blob;
 992        int node = dev_of_offset(dev);
 993        const char *phy_mode;
 994        int fl_node;
 995        int pnode;
 996        unsigned long addr;
 997
 998        pdata->iobase = devfdt_get_addr(dev);
 999        pdata->phy_interface = -1;
1000
1001        pnode = fdt_node_offset_by_compatible(blob, node,
1002                                              "marvell,kirkwood-eth-port");
1003
1004        /* Get phy-mode / phy_interface from DT */
1005        phy_mode = fdt_getprop(gd->fdt_blob, pnode, "phy-mode", NULL);
1006        if (phy_mode)
1007                pdata->phy_interface = phy_get_interface_by_name(phy_mode);
1008        else
1009                pdata->phy_interface = PHY_INTERFACE_MODE_GMII;
1010
1011        dmvgbe->phy_interface = pdata->phy_interface;
1012
1013        /* fetch 'fixed-link' property */
1014        fl_node = fdt_subnode_offset(blob, pnode, "fixed-link");
1015        if (fl_node != -FDT_ERR_NOTFOUND) {
1016                /* set phy_addr to invalid value for fixed link */
1017                dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
1018                dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
1019                dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
1020        } else {
1021                /* Now read phyaddr from DT */
1022                addr = fdtdec_lookup_phandle(blob, pnode, "phy-handle");
1023                if (addr > 0)
1024                        dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
1025        }
1026
1027        return 0;
1028}
1029
1030static const struct udevice_id mvgbe_ids[] = {
1031        { .compatible = "marvell,kirkwood-eth" },
1032        { }
1033};
1034
1035U_BOOT_DRIVER(mvgbe) = {
1036        .name   = "mvgbe",
1037        .id     = UCLASS_ETH,
1038        .of_match = mvgbe_ids,
1039        .ofdata_to_platdata = mvgbe_ofdata_to_platdata,
1040        .probe  = mvgbe_probe,
1041        .ops    = &mvgbe_ops,
1042        .priv_auto_alloc_size = sizeof(struct mvgbe_device),
1043        .platdata_auto_alloc_size = sizeof(struct eth_pdata),
1044};
1045#endif /* CONFIG_DM_ETH */
1046