uboot/arch/powerpc/cpu/mpc8xx/fec.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <command.h>
  10#include <commproc.h>
  11#include <malloc.h>
  12#include <net.h>
  13
  14#include <phy.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18#undef  ET_DEBUG
  19
  20#if defined(CONFIG_CMD_NET) && \
  21        (defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2))
  22
  23/* compatibility test, if only FEC_ENET defined assume ETHER on FEC1 */
  24#if defined(FEC_ENET) && !defined(CONFIG_ETHER_ON_FEC1) && !defined(CONFIG_ETHER_ON_FEC2)
  25#define CONFIG_ETHER_ON_FEC1 1
  26#endif
  27
  28/* define WANT_MII when MII support is required */
  29#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_FEC1_PHY) || defined(CONFIG_FEC2_PHY)
  30#define WANT_MII
  31#else
  32#undef WANT_MII
  33#endif
  34
  35#if defined(WANT_MII)
  36#include <miiphy.h>
  37
  38#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
  39#error "CONFIG_MII has to be defined!"
  40#endif
  41
  42#endif
  43
  44#if defined(CONFIG_RMII) && !defined(WANT_MII)
  45#error RMII support is unusable without a working PHY.
  46#endif
  47
  48#ifdef CONFIG_SYS_DISCOVER_PHY
  49static int mii_discover_phy(struct eth_device *dev);
  50#endif
  51
  52int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg);
  53int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
  54                        u16 value);
  55
  56static struct ether_fcc_info_s
  57{
  58        int ether_index;
  59        int fecp_offset;
  60        int phy_addr;
  61        int actual_phy_addr;
  62        int initialized;
  63}
  64        ether_fcc_info[] = {
  65#if defined(CONFIG_ETHER_ON_FEC1)
  66        {
  67                0,
  68                offsetof(immap_t, im_cpm.cp_fec1),
  69#if defined(CONFIG_FEC1_PHY)
  70                CONFIG_FEC1_PHY,
  71#else
  72                -1,     /* discover */
  73#endif
  74                -1,
  75                0,
  76
  77        },
  78#endif
  79#if defined(CONFIG_ETHER_ON_FEC2)
  80        {
  81                1,
  82                offsetof(immap_t, im_cpm.cp_fec2),
  83#if defined(CONFIG_FEC2_PHY)
  84                CONFIG_FEC2_PHY,
  85#else
  86                -1,
  87#endif
  88                -1,
  89                0,
  90        },
  91#endif
  92};
  93
  94/* Ethernet Transmit and Receive Buffers */
  95#define DBUF_LENGTH  1520
  96
  97#define TX_BUF_CNT 2
  98
  99#define TOUT_LOOP 100
 100
 101#define PKT_MAXBUF_SIZE         1518
 102#define PKT_MINBUF_SIZE         64
 103#define PKT_MAXBLR_SIZE         1520
 104
 105#ifdef __GNUC__
 106static char txbuf[DBUF_LENGTH] __attribute__ ((aligned(8)));
 107#else
 108#error txbuf must be aligned.
 109#endif
 110
 111static uint rxIdx;      /* index of the current RX buffer */
 112static uint txIdx;      /* index of the current TX buffer */
 113
 114/*
 115  * FEC Ethernet Tx and Rx buffer descriptors allocated at the
 116  *  immr->udata_bd address on Dual-Port RAM
 117  * Provide for Double Buffering
 118  */
 119
 120typedef volatile struct CommonBufferDescriptor {
 121    cbd_t rxbd[PKTBUFSRX];              /* Rx BD */
 122    cbd_t txbd[TX_BUF_CNT];             /* Tx BD */
 123} RTXBD;
 124
 125static RTXBD *rtx = NULL;
 126
 127static int fec_send(struct eth_device *dev, void *packet, int length);
 128static int fec_recv(struct eth_device* dev);
 129static int fec_init(struct eth_device* dev, bd_t * bd);
 130static void fec_halt(struct eth_device* dev);
 131#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 132static void __mii_init(void);
 133#endif
 134
 135int fec_initialize(bd_t *bis)
 136{
 137        struct eth_device* dev;
 138        struct ether_fcc_info_s *efis;
 139        int             i;
 140
 141        for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) {
 142
 143                dev = malloc(sizeof(*dev));
 144                if (dev == NULL)
 145                        hang();
 146
 147                memset(dev, 0, sizeof(*dev));
 148
 149                /* for FEC1 make sure that the name of the interface is the same
 150                   as the old one for compatibility reasons */
 151                if (i == 0) {
 152                        strcpy(dev->name, "FEC");
 153                } else {
 154                        sprintf (dev->name, "FEC%d",
 155                                ether_fcc_info[i].ether_index + 1);
 156                }
 157
 158                efis = &ether_fcc_info[i];
 159
 160                /*
 161                 * reset actual phy addr
 162                 */
 163                efis->actual_phy_addr = -1;
 164
 165                dev->priv = efis;
 166                dev->init = fec_init;
 167                dev->halt = fec_halt;
 168                dev->send = fec_send;
 169                dev->recv = fec_recv;
 170
 171                eth_register(dev);
 172
 173#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 174                int retval;
 175                struct mii_dev *mdiodev = mdio_alloc();
 176                if (!mdiodev)
 177                        return -ENOMEM;
 178                strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
 179                mdiodev->read = fec8xx_miiphy_read;
 180                mdiodev->write = fec8xx_miiphy_write;
 181
 182                retval = mdio_register(mdiodev);
 183                if (retval < 0)
 184                        return retval;
 185#endif
 186        }
 187        return 1;
 188}
 189
 190static int fec_send(struct eth_device *dev, void *packet, int length)
 191{
 192        int j, rc;
 193        struct ether_fcc_info_s *efis = dev->priv;
 194        volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 195
 196        /* section 16.9.23.3
 197         * Wait for ready
 198         */
 199        j = 0;
 200        while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
 201                udelay(1);
 202                j++;
 203        }
 204        if (j>=TOUT_LOOP) {
 205                printf("TX not ready\n");
 206        }
 207
 208        rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
 209        rtx->txbd[txIdx].cbd_datlen  = length;
 210        rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
 211        __asm__ ("eieio");
 212
 213        /* Activate transmit Buffer Descriptor polling */
 214        fecp->fec_x_des_active = 0x01000000;    /* Descriptor polling active    */
 215
 216        j = 0;
 217        while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
 218                udelay(1);
 219                j++;
 220        }
 221        if (j>=TOUT_LOOP) {
 222                printf("TX timeout\n");
 223        }
 224#ifdef ET_DEBUG
 225        printf("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
 226        __FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc,
 227        (rtx->txbd[txIdx].cbd_sc & 0x003C)>>2);
 228#endif
 229        /* return only status bits */;
 230        rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
 231
 232        txIdx = (txIdx + 1) % TX_BUF_CNT;
 233
 234        return rc;
 235}
 236
 237static int fec_recv (struct eth_device *dev)
 238{
 239        struct ether_fcc_info_s *efis = dev->priv;
 240        volatile fec_t *fecp =
 241                (volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
 242        int length;
 243
 244        for (;;) {
 245                /* section 16.9.23.2 */
 246                if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
 247                        length = -1;
 248                        break;  /* nothing received - leave for() loop */
 249                }
 250
 251                length = rtx->rxbd[rxIdx].cbd_datlen;
 252
 253                if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
 254#ifdef ET_DEBUG
 255                        printf ("%s[%d] err: %x\n",
 256                                __FUNCTION__, __LINE__,
 257                                rtx->rxbd[rxIdx].cbd_sc);
 258#endif
 259                } else {
 260                        uchar *rx = net_rx_packets[rxIdx];
 261
 262                        length -= 4;
 263
 264#if defined(CONFIG_CMD_CDP)
 265                        if ((rx[0] & 1) != 0 &&
 266                            memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 &&
 267                            !is_cdp_packet((uchar *)rx))
 268                                rx = NULL;
 269#endif
 270                        /*
 271                         * Pass the packet up to the protocol layers.
 272                         */
 273                        if (rx != NULL)
 274                                net_process_received_packet(rx, length);
 275                }
 276
 277                /* Give the buffer back to the FEC. */
 278                rtx->rxbd[rxIdx].cbd_datlen = 0;
 279
 280                /* wrap around buffer index when necessary */
 281                if ((rxIdx + 1) >= PKTBUFSRX) {
 282                        rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
 283                                (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
 284                        rxIdx = 0;
 285                } else {
 286                        rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
 287                        rxIdx++;
 288                }
 289
 290                __asm__ ("eieio");
 291
 292                /* Try to fill Buffer Descriptors */
 293                fecp->fec_r_des_active = 0x01000000;    /* Descriptor polling active    */
 294        }
 295
 296        return length;
 297}
 298
 299/**************************************************************
 300 *
 301 * FEC Ethernet Initialization Routine
 302 *
 303 *************************************************************/
 304
 305#define FEC_ECNTRL_PINMUX       0x00000004
 306#define FEC_ECNTRL_ETHER_EN     0x00000002
 307#define FEC_ECNTRL_RESET        0x00000001
 308
 309#define FEC_RCNTRL_BC_REJ       0x00000010
 310#define FEC_RCNTRL_PROM         0x00000008
 311#define FEC_RCNTRL_MII_MODE     0x00000004
 312#define FEC_RCNTRL_DRT          0x00000002
 313#define FEC_RCNTRL_LOOP         0x00000001
 314
 315#define FEC_TCNTRL_FDEN         0x00000004
 316#define FEC_TCNTRL_HBC          0x00000002
 317#define FEC_TCNTRL_GTS          0x00000001
 318
 319#define FEC_RESET_DELAY         50
 320
 321#if defined(CONFIG_RMII)
 322
 323static inline void fec_10Mbps(struct eth_device *dev)
 324{
 325        struct ether_fcc_info_s *efis = dev->priv;
 326        int fecidx = efis->ether_index;
 327        uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
 328
 329        if ((unsigned int)fecidx >= 2)
 330                hang();
 331
 332        ((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_cptr |=  mask;
 333}
 334
 335static inline void fec_100Mbps(struct eth_device *dev)
 336{
 337        struct ether_fcc_info_s *efis = dev->priv;
 338        int fecidx = efis->ether_index;
 339        uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
 340
 341        if ((unsigned int)fecidx >= 2)
 342                hang();
 343
 344        ((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_cptr &= ~mask;
 345}
 346
 347#endif
 348
 349static inline void fec_full_duplex(struct eth_device *dev)
 350{
 351        struct ether_fcc_info_s *efis = dev->priv;
 352        volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 353
 354        fecp->fec_r_cntrl &= ~FEC_RCNTRL_DRT;
 355        fecp->fec_x_cntrl |=  FEC_TCNTRL_FDEN;  /* FD enable */
 356}
 357
 358static inline void fec_half_duplex(struct eth_device *dev)
 359{
 360        struct ether_fcc_info_s *efis = dev->priv;
 361        volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 362
 363        fecp->fec_r_cntrl |=  FEC_RCNTRL_DRT;
 364        fecp->fec_x_cntrl &= ~FEC_TCNTRL_FDEN;  /* FD disable */
 365}
 366
 367static void fec_pin_init(int fecidx)
 368{
 369        bd_t           *bd = gd->bd;
 370        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 371
 372        /*
 373         * Set MII speed to 2.5 MHz or slightly below.
 374         *
 375         * According to the MPC860T (Rev. D) Fast ethernet controller user
 376         * manual (6.2.14),
 377         * the MII management interface clock must be less than or equal
 378         * to 2.5 MHz.
 379         * This MDC frequency is equal to system clock / (2 * MII_SPEED).
 380         * Then MII_SPEED = system_clock / 2 * 2,5 MHz.
 381         *
 382         * All MII configuration is done via FEC1 registers:
 383         */
 384        immr->im_cpm.cp_fec1.fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
 385
 386#if defined(CONFIG_MPC885_FAMILY) && defined(WANT_MII)
 387        /* use MDC for MII */
 388        immr->im_ioport.iop_pdpar |=  0x0080;
 389        immr->im_ioport.iop_pddir &= ~0x0080;
 390#endif
 391
 392        if (fecidx == 0) {
 393#if defined(CONFIG_ETHER_ON_FEC1)
 394
 395#if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
 396
 397#if !defined(CONFIG_RMII)
 398
 399                immr->im_ioport.iop_papar |=  0xf830;
 400                immr->im_ioport.iop_padir |=  0x0830;
 401                immr->im_ioport.iop_padir &= ~0xf000;
 402
 403                immr->im_cpm.cp_pbpar     |=  0x00001001;
 404                immr->im_cpm.cp_pbdir     &= ~0x00001001;
 405
 406                immr->im_ioport.iop_pcpar |=  0x000c;
 407                immr->im_ioport.iop_pcdir &= ~0x000c;
 408
 409                immr->im_cpm.cp_pepar     |=  0x00000003;
 410                immr->im_cpm.cp_pedir     |=  0x00000003;
 411                immr->im_cpm.cp_peso      &= ~0x00000003;
 412
 413                immr->im_cpm.cp_cptr      &= ~0x00000100;
 414
 415#else
 416
 417#if !defined(CONFIG_FEC1_PHY_NORXERR)
 418                immr->im_ioport.iop_papar |=  0x1000;
 419                immr->im_ioport.iop_padir &= ~0x1000;
 420#endif
 421                immr->im_ioport.iop_papar |=  0xe810;
 422                immr->im_ioport.iop_padir |=  0x0810;
 423                immr->im_ioport.iop_padir &= ~0xe000;
 424
 425                immr->im_cpm.cp_pbpar     |=  0x00000001;
 426                immr->im_cpm.cp_pbdir     &= ~0x00000001;
 427
 428                immr->im_cpm.cp_cptr      |=  0x00000100;
 429                immr->im_cpm.cp_cptr      &= ~0x00000050;
 430
 431#endif /* !CONFIG_RMII */
 432
 433#else
 434                /*
 435                 * Configure all of port D for MII.
 436                 */
 437                immr->im_ioport.iop_pdpar = 0x1fff;
 438
 439                /*
 440                 * Bits moved from Rev. D onward
 441                 */
 442                if ((get_immr(0) & 0xffff) < 0x0501)
 443                        immr->im_ioport.iop_pddir = 0x1c58;     /* Pre rev. D */
 444                else
 445                        immr->im_ioport.iop_pddir = 0x1fff;     /* Rev. D and later */
 446#endif
 447
 448#endif  /* CONFIG_ETHER_ON_FEC1 */
 449        } else if (fecidx == 1) {
 450
 451#if defined(CONFIG_ETHER_ON_FEC2)
 452
 453#if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
 454
 455#if !defined(CONFIG_RMII)
 456                immr->im_cpm.cp_pepar     |=  0x0003fffc;
 457                immr->im_cpm.cp_pedir     |=  0x0003fffc;
 458                immr->im_cpm.cp_peso      &= ~0x000087fc;
 459                immr->im_cpm.cp_peso      |=  0x00037800;
 460
 461                immr->im_cpm.cp_cptr      &= ~0x00000080;
 462#else
 463
 464#if !defined(CONFIG_FEC2_PHY_NORXERR)
 465                immr->im_cpm.cp_pepar     |=  0x00000010;
 466                immr->im_cpm.cp_pedir     |=  0x00000010;
 467                immr->im_cpm.cp_peso      &= ~0x00000010;
 468#endif
 469                immr->im_cpm.cp_pepar     |=  0x00039620;
 470                immr->im_cpm.cp_pedir     |=  0x00039620;
 471                immr->im_cpm.cp_peso      |=  0x00031000;
 472                immr->im_cpm.cp_peso      &= ~0x00008620;
 473
 474                immr->im_cpm.cp_cptr      |=  0x00000080;
 475                immr->im_cpm.cp_cptr      &= ~0x00000028;
 476#endif /* CONFIG_RMII */
 477
 478#endif /* CONFIG_MPC885_FAMILY */
 479
 480#endif /* CONFIG_ETHER_ON_FEC2 */
 481
 482        }
 483}
 484
 485static int fec_reset(volatile fec_t *fecp)
 486{
 487        int i;
 488
 489        /* Whack a reset.
 490         * A delay is required between a reset of the FEC block and
 491         * initialization of other FEC registers because the reset takes
 492         * some time to complete. If you don't delay, subsequent writes
 493         * to FEC registers might get killed by the reset routine which is
 494         * still in progress.
 495         */
 496
 497        fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
 498        for (i = 0;
 499             (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
 500             ++i) {
 501                udelay (1);
 502        }
 503        if (i == FEC_RESET_DELAY)
 504                return -1;
 505
 506        return 0;
 507}
 508
 509static int fec_init (struct eth_device *dev, bd_t * bd)
 510{
 511        struct ether_fcc_info_s *efis = dev->priv;
 512        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 513        volatile fec_t *fecp =
 514                (volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
 515        int i;
 516
 517#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 518        /* the MII interface is connected to FEC1
 519         * so for the miiphy_xxx function to work we must
 520         * call mii_init since fec_halt messes the thing up
 521         */
 522        if (efis->ether_index != 0)
 523                __mii_init();
 524#endif
 525
 526        if (fec_reset(fecp) < 0)
 527                printf ("FEC_RESET_DELAY timeout\n");
 528
 529        /* We use strictly polling mode only
 530         */
 531        fecp->fec_imask = 0;
 532
 533        /* Clear any pending interrupt
 534         */
 535        fecp->fec_ievent = 0xffc0;
 536
 537        /* No need to set the IVEC register */
 538
 539        /* Set station address
 540         */
 541#define ea dev->enetaddr
 542        fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
 543        fecp->fec_addr_high = (ea[4] << 8) | (ea[5]);
 544#undef ea
 545
 546#if defined(CONFIG_CMD_CDP)
 547        /*
 548         * Turn on multicast address hash table
 549         */
 550        fecp->fec_hash_table_high = 0xffffffff;
 551        fecp->fec_hash_table_low = 0xffffffff;
 552#else
 553        /* Clear multicast address hash table
 554         */
 555        fecp->fec_hash_table_high = 0;
 556        fecp->fec_hash_table_low = 0;
 557#endif
 558
 559        /* Set maximum receive buffer size.
 560         */
 561        fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
 562
 563        /* Set maximum frame length
 564         */
 565        fecp->fec_r_hash = PKT_MAXBUF_SIZE;
 566
 567        /*
 568         * Setup Buffers and Buffer Desriptors
 569         */
 570        rxIdx = 0;
 571        txIdx = 0;
 572
 573        if (!rtx)
 574                rtx = (RTXBD *)(immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
 575        /*
 576         * Setup Receiver Buffer Descriptors (13.14.24.18)
 577         * Settings:
 578         *     Empty, Wrap
 579         */
 580        for (i = 0; i < PKTBUFSRX; i++) {
 581                rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
 582                rtx->rxbd[i].cbd_datlen = 0;    /* Reset */
 583                rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
 584        }
 585        rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
 586
 587        /*
 588         * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
 589         * Settings:
 590         *    Last, Tx CRC
 591         */
 592        for (i = 0; i < TX_BUF_CNT; i++) {
 593                rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
 594                rtx->txbd[i].cbd_datlen = 0;    /* Reset */
 595                rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
 596        }
 597        rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
 598
 599        /* Set receive and transmit descriptor base
 600         */
 601        fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
 602        fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
 603
 604        /* Enable MII mode
 605         */
 606#if 0                           /* Full duplex mode */
 607        fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
 608        fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
 609#else  /* Half duplex mode */
 610        fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
 611        fecp->fec_x_cntrl = 0;
 612#endif
 613
 614        /* Enable big endian and don't care about SDMA FC.
 615         */
 616        fecp->fec_fun_code = 0x78000000;
 617
 618        /*
 619         * Setup the pin configuration of the FEC
 620         */
 621        fec_pin_init (efis->ether_index);
 622
 623        rxIdx = 0;
 624        txIdx = 0;
 625
 626        /*
 627         * Now enable the transmit and receive processing
 628         */
 629        fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
 630
 631        if (efis->phy_addr == -1) {
 632#ifdef CONFIG_SYS_DISCOVER_PHY
 633                /*
 634                 * wait for the PHY to wake up after reset
 635                 */
 636                efis->actual_phy_addr = mii_discover_phy (dev);
 637
 638                if (efis->actual_phy_addr == -1) {
 639                        printf ("Unable to discover phy!\n");
 640                        return -1;
 641                }
 642#else
 643                efis->actual_phy_addr = -1;
 644#endif
 645        } else {
 646                efis->actual_phy_addr = efis->phy_addr;
 647        }
 648
 649#if defined(CONFIG_MII) && defined(CONFIG_RMII)
 650        /*
 651         * adapt the RMII speed to the speed of the phy
 652         */
 653        if (miiphy_speed (dev->name, efis->actual_phy_addr) == _100BASET) {
 654                fec_100Mbps (dev);
 655        } else {
 656                fec_10Mbps (dev);
 657        }
 658#endif
 659
 660#if defined(CONFIG_MII)
 661        /*
 662         * adapt to the half/full speed settings
 663         */
 664        if (miiphy_duplex (dev->name, efis->actual_phy_addr) == FULL) {
 665                fec_full_duplex (dev);
 666        } else {
 667                fec_half_duplex (dev);
 668        }
 669#endif
 670
 671        /* And last, try to fill Rx Buffer Descriptors */
 672        fecp->fec_r_des_active = 0x01000000;    /* Descriptor polling active    */
 673
 674        efis->initialized = 1;
 675
 676        return 0;
 677}
 678
 679
 680static void fec_halt(struct eth_device* dev)
 681{
 682        struct ether_fcc_info_s *efis = dev->priv;
 683        volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
 684        int i;
 685
 686        /* avoid halt if initialized; mii gets stuck otherwise */
 687        if (!efis->initialized)
 688                return;
 689
 690        /* Whack a reset.
 691         * A delay is required between a reset of the FEC block and
 692         * initialization of other FEC registers because the reset takes
 693         * some time to complete. If you don't delay, subsequent writes
 694         * to FEC registers might get killed by the reset routine which is
 695         * still in progress.
 696         */
 697
 698        fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
 699        for (i = 0;
 700             (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
 701             ++i) {
 702                udelay (1);
 703        }
 704        if (i == FEC_RESET_DELAY) {
 705                printf ("FEC_RESET_DELAY timeout\n");
 706                return;
 707        }
 708
 709        efis->initialized = 0;
 710}
 711
 712#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 713
 714/* Make MII read/write commands for the FEC.
 715*/
 716
 717#define mk_mii_read(ADDR, REG)  (0x60020000 | ((ADDR << 23) | \
 718                                                (REG & 0x1f) << 18))
 719
 720#define mk_mii_write(ADDR, REG, VAL)    (0x50020000 | ((ADDR << 23) | \
 721                                                (REG & 0x1f) << 18) | \
 722                                                (VAL & 0xffff))
 723
 724/* Interrupt events/masks.
 725*/
 726#define FEC_ENET_HBERR  ((uint)0x80000000)      /* Heartbeat error */
 727#define FEC_ENET_BABR   ((uint)0x40000000)      /* Babbling receiver */
 728#define FEC_ENET_BABT   ((uint)0x20000000)      /* Babbling transmitter */
 729#define FEC_ENET_GRA    ((uint)0x10000000)      /* Graceful stop complete */
 730#define FEC_ENET_TXF    ((uint)0x08000000)      /* Full frame transmitted */
 731#define FEC_ENET_TXB    ((uint)0x04000000)      /* A buffer was transmitted */
 732#define FEC_ENET_RXF    ((uint)0x02000000)      /* Full frame received */
 733#define FEC_ENET_RXB    ((uint)0x01000000)      /* A buffer was received */
 734#define FEC_ENET_MII    ((uint)0x00800000)      /* MII interrupt */
 735#define FEC_ENET_EBERR  ((uint)0x00400000)      /* SDMA bus error */
 736
 737/* PHY identification
 738 */
 739#define PHY_ID_LXT970           0x78100000      /* LXT970 */
 740#define PHY_ID_LXT971           0x001378e0      /* LXT971 and 972 */
 741#define PHY_ID_82555            0x02a80150      /* Intel 82555 */
 742#define PHY_ID_QS6612           0x01814400      /* QS6612 */
 743#define PHY_ID_AMD79C784        0x00225610      /* AMD 79C784 */
 744#define PHY_ID_LSI80225         0x0016f870      /* LSI 80225 */
 745#define PHY_ID_LSI80225B        0x0016f880      /* LSI 80225/B */
 746#define PHY_ID_DM9161           0x0181B880      /* Davicom DM9161 */
 747#define PHY_ID_KSM8995M         0x00221450      /* MICREL KS8995MA */
 748
 749/* send command to phy using mii, wait for result */
 750static uint
 751mii_send(uint mii_cmd)
 752{
 753        uint mii_reply;
 754        volatile fec_t  *ep;
 755        int cnt;
 756
 757        ep = &(((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_fec);
 758
 759        ep->fec_mii_data = mii_cmd;     /* command to phy */
 760
 761        /* wait for mii complete */
 762        cnt = 0;
 763        while (!(ep->fec_ievent & FEC_ENET_MII)) {
 764                if (++cnt > 1000) {
 765                        printf("mii_send STUCK!\n");
 766                        break;
 767                }
 768        }
 769        mii_reply = ep->fec_mii_data;           /* result from phy */
 770        ep->fec_ievent = FEC_ENET_MII;          /* clear MII complete */
 771#if 0
 772        printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
 773                __FILE__,__LINE__,__FUNCTION__,mii_cmd,mii_reply);
 774#endif
 775        return (mii_reply & 0xffff);            /* data read from phy */
 776}
 777#endif
 778
 779#if defined(CONFIG_SYS_DISCOVER_PHY)
 780static int mii_discover_phy(struct eth_device *dev)
 781{
 782#define MAX_PHY_PASSES 11
 783        uint phyno;
 784        int  pass;
 785        uint phytype;
 786        int phyaddr;
 787
 788        phyaddr = -1;   /* didn't find a PHY yet */
 789        for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
 790                if (pass > 1) {
 791                        /* PHY may need more time to recover from reset.
 792                         * The LXT970 needs 50ms typical, no maximum is
 793                         * specified, so wait 10ms before try again.
 794                         * With 11 passes this gives it 100ms to wake up.
 795                         */
 796                        udelay(10000);  /* wait 10ms */
 797                }
 798                for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
 799                        phytype = mii_send(mk_mii_read(phyno, MII_PHYSID2));
 800#ifdef ET_DEBUG
 801                        printf("PHY type 0x%x pass %d type ", phytype, pass);
 802#endif
 803                        if (phytype != 0xffff) {
 804                                phyaddr = phyno;
 805                                phytype |= mii_send(mk_mii_read(phyno,
 806                                                                MII_PHYSID1)) << 16;
 807
 808#ifdef ET_DEBUG
 809                                printf("PHY @ 0x%x pass %d type ",phyno,pass);
 810                                switch (phytype & 0xfffffff0) {
 811                                case PHY_ID_LXT970:
 812                                        printf("LXT970\n");
 813                                        break;
 814                                case PHY_ID_LXT971:
 815                                        printf("LXT971\n");
 816                                        break;
 817                                case PHY_ID_82555:
 818                                        printf("82555\n");
 819                                        break;
 820                                case PHY_ID_QS6612:
 821                                        printf("QS6612\n");
 822                                        break;
 823                                case PHY_ID_AMD79C784:
 824                                        printf("AMD79C784\n");
 825                                        break;
 826                                case PHY_ID_LSI80225B:
 827                                        printf("LSI L80225/B\n");
 828                                        break;
 829                                case PHY_ID_DM9161:
 830                                        printf("Davicom DM9161\n");
 831                                        break;
 832                                case PHY_ID_KSM8995M:
 833                                        printf("MICREL KS8995M\n");
 834                                        break;
 835                                default:
 836                                        printf("0x%08x\n", phytype);
 837                                        break;
 838                                }
 839#endif
 840                        }
 841                }
 842        }
 843        if (phyaddr < 0) {
 844                printf("No PHY device found.\n");
 845        }
 846        return phyaddr;
 847}
 848#endif  /* CONFIG_SYS_DISCOVER_PHY */
 849
 850#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
 851
 852/****************************************************************************
 853 * mii_init -- Initialize the MII via FEC 1 for MII command without ethernet
 854 * This function is a subset of eth_init
 855 ****************************************************************************
 856 */
 857static void __mii_init(void)
 858{
 859        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 860        volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
 861
 862        if (fec_reset(fecp) < 0)
 863                printf ("FEC_RESET_DELAY timeout\n");
 864
 865        /* We use strictly polling mode only
 866         */
 867        fecp->fec_imask = 0;
 868
 869        /* Clear any pending interrupt
 870         */
 871        fecp->fec_ievent = 0xffc0;
 872
 873        /* Now enable the transmit and receive processing
 874         */
 875        fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
 876}
 877
 878void mii_init (void)
 879{
 880        int i;
 881
 882        __mii_init();
 883
 884        /* Setup the pin configuration of the FEC(s)
 885        */
 886        for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++)
 887                fec_pin_init(ether_fcc_info[i].ether_index);
 888}
 889
 890/*****************************************************************************
 891 * Read and write a MII PHY register, routines used by MII Utilities
 892 *
 893 * FIXME: These routines are expected to return 0 on success, but mii_send
 894 *        does _not_ return an error code. Maybe 0xFFFF means error, i.e.
 895 *        no PHY connected...
 896 *        For now always return 0.
 897 * FIXME: These routines only work after calling eth_init() at least once!
 898 *        Otherwise they hang in mii_send() !!! Sorry!
 899 *****************************************************************************/
 900
 901int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
 902{
 903        unsigned short value = 0;
 904        short rdreg;    /* register working value */
 905
 906#ifdef MII_DEBUG
 907        printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
 908#endif
 909        rdreg = mii_send(mk_mii_read(addr, reg));
 910
 911        value = rdreg;
 912#ifdef MII_DEBUG
 913        printf ("0x%04x\n", value);
 914#endif
 915        return value;
 916}
 917
 918int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
 919                        u16 value)
 920{
 921#ifdef MII_DEBUG
 922        printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
 923#endif
 924        (void)mii_send(mk_mii_write(addr, reg, value));
 925
 926#ifdef MII_DEBUG
 927        printf ("0x%04x\n", value);
 928#endif
 929        return 0;
 930}
 931#endif
 932
 933#endif
 934