uboot/drivers/net/davinci_emac.c
<<
>>
Prefs
   1/*
   2 * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
   3 *
   4 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
   5 *
   6 * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
   7 * follows:
   8 *
   9 * ----------------------------------------------------------------------------
  10 *
  11 * dm644x_emac.c
  12 *
  13 * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
  14 *
  15 * Copyright (C) 2005 Texas Instruments.
  16 *
  17 * ----------------------------------------------------------------------------
  18 *
  19 * SPDX-License-Identifier:     GPL-2.0+
  20 *
  21 * Modifications:
  22 * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
  23 * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
  24 */
  25#include <common.h>
  26#include <command.h>
  27#include <net.h>
  28#include <miiphy.h>
  29#include <malloc.h>
  30#include <netdev.h>
  31#include <linux/compiler.h>
  32#include <asm/arch/emac_defs.h>
  33#include <asm/io.h>
  34#include "davinci_emac.h"
  35
  36unsigned int    emac_dbg = 0;
  37#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
  38
  39#ifdef EMAC_HW_RAM_ADDR
  40static inline unsigned long BD_TO_HW(unsigned long x)
  41{
  42        if (x == 0)
  43                return 0;
  44
  45        return x - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR;
  46}
  47
  48static inline unsigned long HW_TO_BD(unsigned long x)
  49{
  50        if (x == 0)
  51                return 0;
  52
  53        return x - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR;
  54}
  55#else
  56#define BD_TO_HW(x)     (x)
  57#define HW_TO_BD(x)     (x)
  58#endif
  59
  60#ifdef DAVINCI_EMAC_GIG_ENABLE
  61#define emac_gigabit_enable(phy_addr)   davinci_eth_gigabit_enable(phy_addr)
  62#else
  63#define emac_gigabit_enable(phy_addr)   /* no gigabit to enable */
  64#endif
  65
  66#if !defined(CONFIG_SYS_EMAC_TI_CLKDIV)
  67#define CONFIG_SYS_EMAC_TI_CLKDIV       ((EMAC_MDIO_BUS_FREQ / \
  68                EMAC_MDIO_CLOCK_FREQ) - 1)
  69#endif
  70
  71static void davinci_eth_mdio_enable(void);
  72
  73static int gen_init_phy(int phy_addr);
  74static int gen_is_phy_connected(int phy_addr);
  75static int gen_get_link_speed(int phy_addr);
  76static int gen_auto_negotiate(int phy_addr);
  77
  78void eth_mdio_enable(void)
  79{
  80        davinci_eth_mdio_enable();
  81}
  82
  83/* EMAC Addresses */
  84static volatile emac_regs       *adap_emac = (emac_regs *)EMAC_BASE_ADDR;
  85static volatile ewrap_regs      *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
  86static volatile mdio_regs       *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
  87
  88/* EMAC descriptors */
  89static volatile emac_desc       *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
  90static volatile emac_desc       *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
  91static volatile emac_desc       *emac_rx_active_head = 0;
  92static volatile emac_desc       *emac_rx_active_tail = 0;
  93static int                      emac_rx_queue_active = 0;
  94
  95/* Receive packet buffers */
  96static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * EMAC_RXBUF_SIZE]
  97                                __aligned(ARCH_DMA_MINALIGN);
  98
  99#ifndef CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT
 100#define CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT       3
 101#endif
 102
 103/* PHY address for a discovered PHY (0xff - not found) */
 104static u_int8_t active_phy_addr[CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT];
 105
 106/* number of PHY found active */
 107static u_int8_t num_phy;
 108
 109phy_t                           phy[CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT];
 110
 111static int davinci_eth_set_mac_addr(struct eth_device *dev)
 112{
 113        unsigned long           mac_hi;
 114        unsigned long           mac_lo;
 115
 116        /*
 117         * Set MAC Addresses & Init multicast Hash to 0 (disable any multicast
 118         * receive)
 119         *  Using channel 0 only - other channels are disabled
 120         *  */
 121        writel(0, &adap_emac->MACINDEX);
 122        mac_hi = (dev->enetaddr[3] << 24) |
 123                 (dev->enetaddr[2] << 16) |
 124                 (dev->enetaddr[1] << 8)  |
 125                 (dev->enetaddr[0]);
 126        mac_lo = (dev->enetaddr[5] << 8) |
 127                 (dev->enetaddr[4]);
 128
 129        writel(mac_hi, &adap_emac->MACADDRHI);
 130#if defined(DAVINCI_EMAC_VERSION2)
 131        writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
 132               &adap_emac->MACADDRLO);
 133#else
 134        writel(mac_lo, &adap_emac->MACADDRLO);
 135#endif
 136
 137        writel(0, &adap_emac->MACHASH1);
 138        writel(0, &adap_emac->MACHASH2);
 139
 140        /* Set source MAC address - REQUIRED */
 141        writel(mac_hi, &adap_emac->MACSRCADDRHI);
 142        writel(mac_lo, &adap_emac->MACSRCADDRLO);
 143
 144
 145        return 0;
 146}
 147
 148static void davinci_eth_mdio_enable(void)
 149{
 150        u_int32_t       clkdiv;
 151
 152        clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV;
 153
 154        writel((clkdiv & 0xff) |
 155               MDIO_CONTROL_ENABLE |
 156               MDIO_CONTROL_FAULT |
 157               MDIO_CONTROL_FAULT_ENABLE,
 158               &adap_mdio->CONTROL);
 159
 160        while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
 161                ;
 162}
 163
 164/*
 165 * Tries to find an active connected PHY. Returns 1 if address if found.
 166 * If no active PHY (or more than one PHY) found returns 0.
 167 * Sets active_phy_addr variable.
 168 */
 169static int davinci_eth_phy_detect(void)
 170{
 171        u_int32_t       phy_act_state;
 172        int             i;
 173        int             j;
 174        unsigned int    count = 0;
 175
 176        for (i = 0; i < CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT; i++)
 177                active_phy_addr[i] = 0xff;
 178
 179        udelay(1000);
 180        phy_act_state = readl(&adap_mdio->ALIVE);
 181
 182        if (phy_act_state == 0)
 183                return 0;               /* No active PHYs */
 184
 185        debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
 186
 187        for (i = 0, j = 0; i < 32; i++)
 188                if (phy_act_state & (1 << i)) {
 189                        count++;
 190                        if (count <= CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT) {
 191                                active_phy_addr[j++] = i;
 192                        } else {
 193                                printf("%s: to many PHYs detected.\n",
 194                                        __func__);
 195                                count = 0;
 196                                break;
 197                        }
 198                }
 199
 200        num_phy = count;
 201
 202        return count;
 203}
 204
 205
 206/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
 207int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
 208{
 209        int     tmp;
 210
 211        while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
 212                ;
 213
 214        writel(MDIO_USERACCESS0_GO |
 215               MDIO_USERACCESS0_WRITE_READ |
 216               ((reg_num & 0x1f) << 21) |
 217               ((phy_addr & 0x1f) << 16),
 218               &adap_mdio->USERACCESS0);
 219
 220        /* Wait for command to complete */
 221        while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
 222                ;
 223
 224        if (tmp & MDIO_USERACCESS0_ACK) {
 225                *data = tmp & 0xffff;
 226                return 1;
 227        }
 228
 229        return 0;
 230}
 231
 232/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
 233int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
 234{
 235
 236        while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
 237                ;
 238
 239        writel(MDIO_USERACCESS0_GO |
 240               MDIO_USERACCESS0_WRITE_WRITE |
 241               ((reg_num & 0x1f) << 21) |
 242               ((phy_addr & 0x1f) << 16) |
 243               (data & 0xffff),
 244               &adap_mdio->USERACCESS0);
 245
 246        /* Wait for command to complete */
 247        while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
 248                ;
 249
 250        return 1;
 251}
 252
 253/* PHY functions for a generic PHY */
 254static int gen_init_phy(int phy_addr)
 255{
 256        int     ret = 1;
 257
 258        if (gen_get_link_speed(phy_addr)) {
 259                /* Try another time */
 260                ret = gen_get_link_speed(phy_addr);
 261        }
 262
 263        return(ret);
 264}
 265
 266static int gen_is_phy_connected(int phy_addr)
 267{
 268        u_int16_t       dummy;
 269
 270        return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
 271}
 272
 273static int get_active_phy(void)
 274{
 275        int i;
 276
 277        for (i = 0; i < num_phy; i++)
 278                if (phy[i].get_link_speed(active_phy_addr[i]))
 279                        return i;
 280
 281        return -1;      /* Return error if no link */
 282}
 283
 284static int gen_get_link_speed(int phy_addr)
 285{
 286        u_int16_t       tmp;
 287
 288        if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) &&
 289                        (tmp & 0x04)) {
 290#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
 291                defined(CONFIG_MACH_DAVINCI_DA850_EVM)
 292                davinci_eth_phy_read(phy_addr, MII_LPA, &tmp);
 293
 294                /* Speed doesn't matter, there is no setting for it in EMAC. */
 295                if (tmp & (LPA_100FULL | LPA_10FULL)) {
 296                        /* set EMAC for Full Duplex  */
 297                        writel(EMAC_MACCONTROL_MIIEN_ENABLE |
 298                                        EMAC_MACCONTROL_FULLDUPLEX_ENABLE,
 299                                        &adap_emac->MACCONTROL);
 300                } else {
 301                        /*set EMAC for Half Duplex  */
 302                        writel(EMAC_MACCONTROL_MIIEN_ENABLE,
 303                                        &adap_emac->MACCONTROL);
 304                }
 305
 306                if (tmp & (LPA_100FULL | LPA_100HALF))
 307                        writel(readl(&adap_emac->MACCONTROL) |
 308                                        EMAC_MACCONTROL_RMIISPEED_100,
 309                                         &adap_emac->MACCONTROL);
 310                else
 311                        writel(readl(&adap_emac->MACCONTROL) &
 312                                        ~EMAC_MACCONTROL_RMIISPEED_100,
 313                                         &adap_emac->MACCONTROL);
 314#endif
 315                return(1);
 316        }
 317
 318        return(0);
 319}
 320
 321static int gen_auto_negotiate(int phy_addr)
 322{
 323        u_int16_t       tmp;
 324        u_int16_t       val;
 325        unsigned long   cntr = 0;
 326
 327        if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
 328                return 0;
 329
 330        val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE |
 331                                                BMCR_SPEED100;
 332        davinci_eth_phy_write(phy_addr, MII_BMCR, val);
 333
 334        if (!davinci_eth_phy_read(phy_addr, MII_ADVERTISE, &val))
 335                return 0;
 336
 337        val |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL |
 338                                                        ADVERTISE_10HALF);
 339        davinci_eth_phy_write(phy_addr, MII_ADVERTISE, val);
 340
 341        if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
 342                return(0);
 343
 344#ifdef DAVINCI_EMAC_GIG_ENABLE
 345        davinci_eth_phy_read(phy_addr, MII_CTRL1000, &val);
 346        val |= PHY_1000BTCR_1000FD;
 347        val &= ~PHY_1000BTCR_1000HD;
 348        davinci_eth_phy_write(phy_addr, MII_CTRL1000, val);
 349        davinci_eth_phy_read(phy_addr, MII_CTRL1000, &val);
 350#endif
 351
 352        /* Restart Auto_negotiation  */
 353        tmp |= BMCR_ANRESTART;
 354        davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
 355
 356        /*check AutoNegotiate complete */
 357        do {
 358                udelay(40000);
 359                if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
 360                        return 0;
 361
 362                if (tmp & BMSR_ANEGCOMPLETE)
 363                        break;
 364
 365                cntr++;
 366        } while (cntr < 200);
 367
 368        if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
 369                return(0);
 370
 371        if (!(tmp & BMSR_ANEGCOMPLETE))
 372                return(0);
 373
 374        return(gen_get_link_speed(phy_addr));
 375}
 376/* End of generic PHY functions */
 377
 378
 379#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 380static int davinci_mii_phy_read(struct mii_dev *bus, int addr, int devad,
 381                                int reg)
 382{
 383        unsigned short value = 0;
 384        int retval = davinci_eth_phy_read(addr, reg, &value);
 385
 386        return retval ? value : -EIO;
 387}
 388
 389static int davinci_mii_phy_write(struct mii_dev *bus, int addr, int devad,
 390                                 int reg, u16 value)
 391{
 392        return davinci_eth_phy_write(addr, reg, value) ? 0 : 1;
 393}
 394#endif
 395
 396static void  __attribute__((unused)) davinci_eth_gigabit_enable(int phy_addr)
 397{
 398        u_int16_t data;
 399
 400        if (davinci_eth_phy_read(phy_addr, 0, &data)) {
 401                if (data & (1 << 6)) { /* speed selection MSB */
 402                        /*
 403                         * Check if link detected is giga-bit
 404                         * If Gigabit mode detected, enable gigbit in MAC
 405                         */
 406                        writel(readl(&adap_emac->MACCONTROL) |
 407                                EMAC_MACCONTROL_GIGFORCE |
 408                                EMAC_MACCONTROL_GIGABIT_ENABLE,
 409                                &adap_emac->MACCONTROL);
 410                }
 411        }
 412}
 413
 414/* Eth device open */
 415static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 416{
 417        dv_reg_p                addr;
 418        u_int32_t               clkdiv, cnt, mac_control;
 419        uint16_t                __maybe_unused lpa_val;
 420        volatile emac_desc      *rx_desc;
 421        int                     index;
 422
 423        debug_emac("+ emac_open\n");
 424
 425        /* Reset EMAC module and disable interrupts in wrapper */
 426        writel(1, &adap_emac->SOFTRESET);
 427        while (readl(&adap_emac->SOFTRESET) != 0)
 428                ;
 429#if defined(DAVINCI_EMAC_VERSION2)
 430        writel(1, &adap_ewrap->softrst);
 431        while (readl(&adap_ewrap->softrst) != 0)
 432                ;
 433#else
 434        writel(0, &adap_ewrap->EWCTL);
 435        for (cnt = 0; cnt < 5; cnt++) {
 436                clkdiv = readl(&adap_ewrap->EWCTL);
 437        }
 438#endif
 439
 440#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
 441        defined(CONFIG_MACH_DAVINCI_DA850_EVM)
 442        adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
 443        adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
 444        adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
 445#endif
 446        rx_desc = emac_rx_desc;
 447
 448        writel(1, &adap_emac->TXCONTROL);
 449        writel(1, &adap_emac->RXCONTROL);
 450
 451        davinci_eth_set_mac_addr(dev);
 452
 453        /* Set DMA 8 TX / 8 RX Head pointers to 0 */
 454        addr = &adap_emac->TX0HDP;
 455        for (cnt = 0; cnt < 8; cnt++)
 456                writel(0, addr++);
 457
 458        addr = &adap_emac->RX0HDP;
 459        for (cnt = 0; cnt < 8; cnt++)
 460                writel(0, addr++);
 461
 462        /* Clear Statistics (do this before setting MacControl register) */
 463        addr = &adap_emac->RXGOODFRAMES;
 464        for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
 465                writel(0, addr++);
 466
 467        /* No multicast addressing */
 468        writel(0, &adap_emac->MACHASH1);
 469        writel(0, &adap_emac->MACHASH2);
 470
 471        /* Create RX queue and set receive process in place */
 472        emac_rx_active_head = emac_rx_desc;
 473        for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
 474                rx_desc->next = BD_TO_HW((u_int32_t)(rx_desc + 1));
 475                rx_desc->buffer = &emac_rx_buffers[cnt * EMAC_RXBUF_SIZE];
 476                rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
 477                rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
 478                rx_desc++;
 479        }
 480
 481        /* Finalize the rx desc list */
 482        rx_desc--;
 483        rx_desc->next = 0;
 484        emac_rx_active_tail = rx_desc;
 485        emac_rx_queue_active = 1;
 486
 487        /* Enable TX/RX */
 488        writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
 489        writel(0, &adap_emac->RXBUFFEROFFSET);
 490
 491        /*
 492         * No fancy configs - Use this for promiscous debug
 493         *   - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
 494         */
 495        writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);
 496
 497        /* Enable ch 0 only */
 498        writel(1, &adap_emac->RXUNICASTSET);
 499
 500        /* Init MDIO & get link state */
 501        clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV;
 502        writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
 503               &adap_mdio->CONTROL);
 504
 505        /* We need to wait for MDIO to start */
 506        udelay(1000);
 507
 508        index = get_active_phy();
 509        if (index == -1)
 510                return(0);
 511
 512        /* Enable MII interface */
 513        mac_control = EMAC_MACCONTROL_MIIEN_ENABLE;
 514#ifdef DAVINCI_EMAC_GIG_ENABLE
 515        davinci_eth_phy_read(active_phy_addr[index], MII_STAT1000, &lpa_val);
 516        if (lpa_val & PHY_1000BTSR_1000FD) {
 517                debug_emac("eth_open : gigabit negotiated\n");
 518                mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
 519                mac_control |= EMAC_MACCONTROL_GIGABIT_ENABLE;
 520        }
 521#endif
 522
 523        davinci_eth_phy_read(active_phy_addr[index], MII_LPA, &lpa_val);
 524        if (lpa_val & (LPA_100FULL | LPA_10FULL))
 525                /* set EMAC for Full Duplex  */
 526                mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
 527#if defined(CONFIG_SOC_DA8XX) || \
 528        (defined(CONFIG_OMAP34XX) && defined(CONFIG_DRIVER_TI_EMAC_USE_RMII))
 529        mac_control |= EMAC_MACCONTROL_RMIISPEED_100;
 530#endif
 531        writel(mac_control, &adap_emac->MACCONTROL);
 532        /* Start receive process */
 533        writel(BD_TO_HW((u_int32_t)emac_rx_desc), &adap_emac->RX0HDP);
 534
 535        debug_emac("- emac_open\n");
 536
 537        return(1);
 538}
 539
 540/* EMAC Channel Teardown */
 541static void davinci_eth_ch_teardown(int ch)
 542{
 543        dv_reg          dly = 0xff;
 544        dv_reg          cnt;
 545
 546        debug_emac("+ emac_ch_teardown\n");
 547
 548        if (ch == EMAC_CH_TX) {
 549                /* Init TX channel teardown */
 550                writel(0, &adap_emac->TXTEARDOWN);
 551                do {
 552                        /*
 553                         * Wait here for Tx teardown completion interrupt to
 554                         * occur. Note: A task delay can be called here to pend
 555                         * rather than occupying CPU cycles - anyway it has
 556                         * been found that teardown takes very few cpu cycles
 557                         * and does not affect functionality
 558                         */
 559                        dly--;
 560                        udelay(1);
 561                        if (dly == 0)
 562                                break;
 563                        cnt = readl(&adap_emac->TX0CP);
 564                } while (cnt != 0xfffffffc);
 565                writel(cnt, &adap_emac->TX0CP);
 566                writel(0, &adap_emac->TX0HDP);
 567        } else {
 568                /* Init RX channel teardown */
 569                writel(0, &adap_emac->RXTEARDOWN);
 570                do {
 571                        /*
 572                         * Wait here for Rx teardown completion interrupt to
 573                         * occur. Note: A task delay can be called here to pend
 574                         * rather than occupying CPU cycles - anyway it has
 575                         * been found that teardown takes very few cpu cycles
 576                         * and does not affect functionality
 577                         */
 578                        dly--;
 579                        udelay(1);
 580                        if (dly == 0)
 581                                break;
 582                        cnt = readl(&adap_emac->RX0CP);
 583                } while (cnt != 0xfffffffc);
 584                writel(cnt, &adap_emac->RX0CP);
 585                writel(0, &adap_emac->RX0HDP);
 586        }
 587
 588        debug_emac("- emac_ch_teardown\n");
 589}
 590
 591/* Eth device close */
 592static void davinci_eth_close(struct eth_device *dev)
 593{
 594        debug_emac("+ emac_close\n");
 595
 596        davinci_eth_ch_teardown(EMAC_CH_TX);    /* TX Channel teardown */
 597        if (readl(&adap_emac->RXCONTROL) & 1)
 598                davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */
 599
 600        /* Reset EMAC module and disable interrupts in wrapper */
 601        writel(1, &adap_emac->SOFTRESET);
 602#if defined(DAVINCI_EMAC_VERSION2)
 603        writel(1, &adap_ewrap->softrst);
 604#else
 605        writel(0, &adap_ewrap->EWCTL);
 606#endif
 607
 608#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
 609        defined(CONFIG_MACH_DAVINCI_DA850_EVM)
 610        adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
 611        adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
 612        adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
 613#endif
 614        debug_emac("- emac_close\n");
 615}
 616
 617static int tx_send_loop = 0;
 618
 619/*
 620 * This function sends a single packet on the network and returns
 621 * positive number (number of bytes transmitted) or negative for error
 622 */
 623static int davinci_eth_send_packet (struct eth_device *dev,
 624                                        void *packet, int length)
 625{
 626        int ret_status = -1;
 627        int index;
 628        tx_send_loop = 0;
 629
 630        index = get_active_phy();
 631        if (index == -1) {
 632                printf(" WARN: emac_send_packet: No link\n");
 633                return (ret_status);
 634        }
 635
 636        /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
 637        if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
 638                length = EMAC_MIN_ETHERNET_PKT_SIZE;
 639        }
 640
 641        /* Populate the TX descriptor */
 642        emac_tx_desc->next = 0;
 643        emac_tx_desc->buffer = (u_int8_t *) packet;
 644        emac_tx_desc->buff_off_len = (length & 0xffff);
 645        emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
 646                                      EMAC_CPPI_SOP_BIT |
 647                                      EMAC_CPPI_OWNERSHIP_BIT |
 648                                      EMAC_CPPI_EOP_BIT);
 649
 650        flush_dcache_range((unsigned long)packet,
 651                           (unsigned long)packet + ALIGN(length, PKTALIGN));
 652
 653        /* Send the packet */
 654        writel(BD_TO_HW((unsigned long)emac_tx_desc), &adap_emac->TX0HDP);
 655
 656        /* Wait for packet to complete or link down */
 657        while (1) {
 658                if (!phy[index].get_link_speed(active_phy_addr[index])) {
 659                        davinci_eth_ch_teardown (EMAC_CH_TX);
 660                        return (ret_status);
 661                }
 662
 663                if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
 664                        ret_status = length;
 665                        break;
 666                }
 667                tx_send_loop++;
 668        }
 669
 670        return (ret_status);
 671}
 672
 673/*
 674 * This function handles receipt of a packet from the network
 675 */
 676static int davinci_eth_rcv_packet (struct eth_device *dev)
 677{
 678        volatile emac_desc *rx_curr_desc;
 679        volatile emac_desc *curr_desc;
 680        volatile emac_desc *tail_desc;
 681        int status, ret = -1;
 682
 683        rx_curr_desc = emac_rx_active_head;
 684        if (!rx_curr_desc)
 685                return 0;
 686        status = rx_curr_desc->pkt_flag_len;
 687        if ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0) {
 688                if (status & EMAC_CPPI_RX_ERROR_FRAME) {
 689                        /* Error in packet - discard it and requeue desc */
 690                        printf ("WARN: emac_rcv_pkt: Error in packet\n");
 691                } else {
 692                        unsigned long tmp = (unsigned long)rx_curr_desc->buffer;
 693                        unsigned short len =
 694                                rx_curr_desc->buff_off_len & 0xffff;
 695
 696                        invalidate_dcache_range(tmp, tmp + ALIGN(len, PKTALIGN));
 697                        net_process_received_packet(rx_curr_desc->buffer, len);
 698                        ret = len;
 699                }
 700
 701                /* Ack received packet descriptor */
 702                writel(BD_TO_HW((ulong)rx_curr_desc), &adap_emac->RX0CP);
 703                curr_desc = rx_curr_desc;
 704                emac_rx_active_head =
 705                        (volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next));
 706
 707                if (status & EMAC_CPPI_EOQ_BIT) {
 708                        if (emac_rx_active_head) {
 709                                writel(BD_TO_HW((ulong)emac_rx_active_head),
 710                                       &adap_emac->RX0HDP);
 711                        } else {
 712                                emac_rx_queue_active = 0;
 713                                printf ("INFO:emac_rcv_packet: RX Queue not active\n");
 714                        }
 715                }
 716
 717                /* Recycle RX descriptor */
 718                rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
 719                rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
 720                rx_curr_desc->next = 0;
 721
 722                if (emac_rx_active_head == 0) {
 723                        printf ("INFO: emac_rcv_pkt: active queue head = 0\n");
 724                        emac_rx_active_head = curr_desc;
 725                        emac_rx_active_tail = curr_desc;
 726                        if (emac_rx_queue_active != 0) {
 727                                writel(BD_TO_HW((ulong)emac_rx_active_head),
 728                                       &adap_emac->RX0HDP);
 729                                printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
 730                                emac_rx_queue_active = 1;
 731                        }
 732                } else {
 733                        tail_desc = emac_rx_active_tail;
 734                        emac_rx_active_tail = curr_desc;
 735                        tail_desc->next = BD_TO_HW((ulong) curr_desc);
 736                        status = tail_desc->pkt_flag_len;
 737                        if (status & EMAC_CPPI_EOQ_BIT) {
 738                                writel(BD_TO_HW((ulong)curr_desc),
 739                                       &adap_emac->RX0HDP);
 740                                status &= ~EMAC_CPPI_EOQ_BIT;
 741                                tail_desc->pkt_flag_len = status;
 742                        }
 743                }
 744                return (ret);
 745        }
 746        return (0);
 747}
 748
 749/*
 750 * This function initializes the emac hardware. It does NOT initialize
 751 * EMAC modules power or pin multiplexors, that is done by board_init()
 752 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 753 */
 754int davinci_emac_initialize(void)
 755{
 756        u_int32_t       phy_id;
 757        u_int16_t       tmp;
 758        int             i;
 759        int             ret;
 760        struct eth_device *dev;
 761
 762        dev = malloc(sizeof *dev);
 763
 764        if (dev == NULL)
 765                return -1;
 766
 767        memset(dev, 0, sizeof *dev);
 768        strcpy(dev->name, "DaVinci-EMAC");
 769
 770        dev->iobase = 0;
 771        dev->init = davinci_eth_open;
 772        dev->halt = davinci_eth_close;
 773        dev->send = davinci_eth_send_packet;
 774        dev->recv = davinci_eth_rcv_packet;
 775        dev->write_hwaddr = davinci_eth_set_mac_addr;
 776
 777        eth_register(dev);
 778
 779        davinci_eth_mdio_enable();
 780
 781        /* let the EMAC detect the PHYs */
 782        udelay(5000);
 783
 784        for (i = 0; i < 256; i++) {
 785                if (readl(&adap_mdio->ALIVE))
 786                        break;
 787                udelay(1000);
 788        }
 789
 790        if (i >= 256) {
 791                printf("No ETH PHY detected!!!\n");
 792                return(0);
 793        }
 794
 795        /* Find if PHY(s) is/are connected */
 796        ret = davinci_eth_phy_detect();
 797        if (!ret)
 798                return(0);
 799        else
 800                debug_emac(" %d ETH PHY detected\n", ret);
 801
 802        /* Get PHY ID and initialize phy_ops for a detected PHY */
 803        for (i = 0; i < num_phy; i++) {
 804                if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1,
 805                                                        &tmp)) {
 806                        active_phy_addr[i] = 0xff;
 807                        continue;
 808                }
 809
 810                phy_id = (tmp << 16) & 0xffff0000;
 811
 812                if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2,
 813                                                        &tmp)) {
 814                        active_phy_addr[i] = 0xff;
 815                        continue;
 816                }
 817
 818                phy_id |= tmp & 0x0000ffff;
 819
 820                switch (phy_id) {
 821#ifdef PHY_KSZ8873
 822                case PHY_KSZ8873:
 823                        sprintf(phy[i].name, "KSZ8873 @ 0x%02x",
 824                                                active_phy_addr[i]);
 825                        phy[i].init = ksz8873_init_phy;
 826                        phy[i].is_phy_connected = ksz8873_is_phy_connected;
 827                        phy[i].get_link_speed = ksz8873_get_link_speed;
 828                        phy[i].auto_negotiate = ksz8873_auto_negotiate;
 829                        break;
 830#endif
 831#ifdef PHY_LXT972
 832                case PHY_LXT972:
 833                        sprintf(phy[i].name, "LXT972 @ 0x%02x",
 834                                                active_phy_addr[i]);
 835                        phy[i].init = lxt972_init_phy;
 836                        phy[i].is_phy_connected = lxt972_is_phy_connected;
 837                        phy[i].get_link_speed = lxt972_get_link_speed;
 838                        phy[i].auto_negotiate = lxt972_auto_negotiate;
 839                        break;
 840#endif
 841#ifdef PHY_DP83848
 842                case PHY_DP83848:
 843                        sprintf(phy[i].name, "DP83848 @ 0x%02x",
 844                                                active_phy_addr[i]);
 845                        phy[i].init = dp83848_init_phy;
 846                        phy[i].is_phy_connected = dp83848_is_phy_connected;
 847                        phy[i].get_link_speed = dp83848_get_link_speed;
 848                        phy[i].auto_negotiate = dp83848_auto_negotiate;
 849                        break;
 850#endif
 851#ifdef PHY_ET1011C
 852                case PHY_ET1011C:
 853                        sprintf(phy[i].name, "ET1011C @ 0x%02x",
 854                                                active_phy_addr[i]);
 855                        phy[i].init = gen_init_phy;
 856                        phy[i].is_phy_connected = gen_is_phy_connected;
 857                        phy[i].get_link_speed = et1011c_get_link_speed;
 858                        phy[i].auto_negotiate = gen_auto_negotiate;
 859                        break;
 860#endif
 861                default:
 862                        sprintf(phy[i].name, "GENERIC @ 0x%02x",
 863                                                active_phy_addr[i]);
 864                        phy[i].init = gen_init_phy;
 865                        phy[i].is_phy_connected = gen_is_phy_connected;
 866                        phy[i].get_link_speed = gen_get_link_speed;
 867                        phy[i].auto_negotiate = gen_auto_negotiate;
 868                }
 869
 870                debug("Ethernet PHY: %s\n", phy[i].name);
 871
 872                int retval;
 873                struct mii_dev *mdiodev = mdio_alloc();
 874                if (!mdiodev)
 875                        return -ENOMEM;
 876                strncpy(mdiodev->name, phy[i].name, MDIO_NAME_LEN);
 877                mdiodev->read = davinci_mii_phy_read;
 878                mdiodev->write = davinci_mii_phy_write;
 879
 880                retval = mdio_register(mdiodev);
 881                if (retval < 0)
 882                        return retval;
 883#ifdef DAVINCI_EMAC_GIG_ENABLE
 884#define PHY_CONF_REG    22
 885                /* Enable PHY to clock out TX_CLK */
 886                davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
 887                tmp |= PHY_CONF_TXCLKEN;
 888                davinci_eth_phy_write(active_phy_addr[i], PHY_CONF_REG, tmp);
 889                davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
 890#endif
 891        }
 892
 893#if defined(CONFIG_TI816X) || (defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
 894                defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \
 895                        !defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE))
 896        for (i = 0; i < num_phy; i++) {
 897                if (phy[i].is_phy_connected(i))
 898                        phy[i].auto_negotiate(i);
 899        }
 900#endif
 901        return(1);
 902}
 903