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