uboot/drivers/net/fm/eth.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2009-2012 Freescale Semiconductor, Inc.
   4 *      Dave Liu <daveliu@freescale.com>
   5 */
   6#include <common.h>
   7#include <asm/io.h>
   8#include <malloc.h>
   9#include <net.h>
  10#include <hwconfig.h>
  11#include <fm_eth.h>
  12#include <fsl_mdio.h>
  13#include <miiphy.h>
  14#include <phy.h>
  15#include <fsl_dtsec.h>
  16#include <fsl_tgec.h>
  17#include <fsl_memac.h>
  18
  19#include "fm.h"
  20
  21static struct eth_device *devlist[NUM_FM_PORTS];
  22static int num_controllers;
  23
  24#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII)
  25
  26#define TBIANA_SETTINGS (TBIANA_ASYMMETRIC_PAUSE | TBIANA_SYMMETRIC_PAUSE | \
  27                         TBIANA_FULL_DUPLEX)
  28
  29#define TBIANA_SGMII_ACK 0x4001
  30
  31#define TBICR_SETTINGS (TBICR_ANEG_ENABLE | TBICR_RESTART_ANEG | \
  32                        TBICR_FULL_DUPLEX | TBICR_SPEED1_SET)
  33
  34/* Configure the TBI for SGMII operation */
  35static void dtsec_configure_serdes(struct fm_eth *priv)
  36{
  37#ifdef CONFIG_SYS_FMAN_V3
  38        u32 value;
  39        struct mii_dev bus;
  40        bus.priv = priv->mac->phyregs;
  41        bool sgmii_2500 = (priv->enet_if ==
  42                        PHY_INTERFACE_MODE_SGMII_2500) ? true : false;
  43        int i = 0;
  44
  45qsgmii_loop:
  46        /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
  47        if (sgmii_2500)
  48                value = PHY_SGMII_CR_PHY_RESET |
  49                        PHY_SGMII_IF_SPEED_GIGABIT |
  50                        PHY_SGMII_IF_MODE_SGMII;
  51        else
  52                value = PHY_SGMII_IF_MODE_SGMII | PHY_SGMII_IF_MODE_AN;
  53
  54        memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x14, value);
  55
  56        /* Dev ability according to SGMII specification */
  57        value = PHY_SGMII_DEV_ABILITY_SGMII;
  58        memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x4, value);
  59
  60        if (sgmii_2500) {
  61                /* Adjust link timer for 2.5G SGMII,
  62                 * 1.6 ms in units of 3.2 ns:
  63                 * 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
  64                 */
  65                memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x0007);
  66                memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xa120);
  67        } else {
  68                /* Adjust link timer for SGMII,
  69                 * 1.6 ms in units of 8 ns:
  70                 * 1.6ms / 8ns = 2 * 10^5 = 0x30d40.
  71                 */
  72                memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x0003);
  73                memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0x0d40);
  74        }
  75
  76        /* Restart AN */
  77        value = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
  78        memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0, value);
  79
  80        if ((priv->enet_if == PHY_INTERFACE_MODE_QSGMII) && (i < 3)) {
  81                i++;
  82                goto qsgmii_loop;
  83        }
  84#else
  85        struct dtsec *regs = priv->mac->base;
  86        struct tsec_mii_mng *phyregs = priv->mac->phyregs;
  87
  88        /*
  89         * Access TBI PHY registers at given TSEC register offset as
  90         * opposed to the register offset used for external PHY accesses
  91         */
  92        tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0, TBI_TBICON,
  93                        TBICON_CLK_SELECT);
  94        tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0, TBI_ANA,
  95                        TBIANA_SGMII_ACK);
  96        tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0,
  97                        TBI_CR, TBICR_SETTINGS);
  98#endif
  99}
 100
 101static void dtsec_init_phy(struct eth_device *dev)
 102{
 103        struct fm_eth *fm_eth = dev->priv;
 104#ifndef CONFIG_SYS_FMAN_V3
 105        struct dtsec *regs = (struct dtsec *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR;
 106
 107        /* Assign a Physical address to the TBI */
 108        out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
 109#endif
 110
 111        if (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII ||
 112            fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII ||
 113            fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500)
 114                dtsec_configure_serdes(fm_eth);
 115}
 116
 117#ifdef CONFIG_PHYLIB
 118static int tgec_is_fibre(struct eth_device *dev)
 119{
 120        struct fm_eth *fm = dev->priv;
 121        char phyopt[20];
 122
 123        sprintf(phyopt, "fsl_fm%d_xaui_phy", fm->fm_index + 1);
 124
 125        return hwconfig_arg_cmp(phyopt, "xfi");
 126}
 127#endif
 128#endif
 129
 130static u16 muram_readw(u16 *addr)
 131{
 132        ulong base = (ulong)addr & ~0x3UL;
 133        u32 val32 = in_be32((void *)base);
 134        int byte_pos;
 135        u16 ret;
 136
 137        byte_pos = (ulong)addr & 0x3UL;
 138        if (byte_pos)
 139                ret = (u16)(val32 & 0x0000ffff);
 140        else
 141                ret = (u16)((val32 & 0xffff0000) >> 16);
 142
 143        return ret;
 144}
 145
 146static void muram_writew(u16 *addr, u16 val)
 147{
 148        ulong base = (ulong)addr & ~0x3UL;
 149        u32 org32 = in_be32((void *)base);
 150        u32 val32;
 151        int byte_pos;
 152
 153        byte_pos = (ulong)addr & 0x3UL;
 154        if (byte_pos)
 155                val32 = (org32 & 0xffff0000) | val;
 156        else
 157                val32 = (org32 & 0x0000ffff) | ((u32)val << 16);
 158
 159        out_be32((void *)base, val32);
 160}
 161
 162static void bmi_rx_port_disable(struct fm_bmi_rx_port *rx_port)
 163{
 164        int timeout = 1000000;
 165
 166        clrbits_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_EN);
 167
 168        /* wait until the rx port is not busy */
 169        while ((in_be32(&rx_port->fmbm_rst) & FMBM_RST_BSY) && timeout--)
 170                ;
 171}
 172
 173static void bmi_rx_port_init(struct fm_bmi_rx_port *rx_port)
 174{
 175        /* set BMI to independent mode, Rx port disable */
 176        out_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_IM);
 177        /* clear FOF in IM case */
 178        out_be32(&rx_port->fmbm_rim, 0);
 179        /* Rx frame next engine -RISC */
 180        out_be32(&rx_port->fmbm_rfne, NIA_ENG_RISC | NIA_RISC_AC_IM_RX);
 181        /* Rx command attribute - no order, MR[3] = 1 */
 182        clrbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_ORDER | FMBM_RFCA_MR_MASK);
 183        setbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_MR(4));
 184        /* enable Rx statistic counters */
 185        out_be32(&rx_port->fmbm_rstc, FMBM_RSTC_EN);
 186        /* disable Rx performance counters */
 187        out_be32(&rx_port->fmbm_rpc, 0);
 188}
 189
 190static void bmi_tx_port_disable(struct fm_bmi_tx_port *tx_port)
 191{
 192        int timeout = 1000000;
 193
 194        clrbits_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_EN);
 195
 196        /* wait until the tx port is not busy */
 197        while ((in_be32(&tx_port->fmbm_tst) & FMBM_TST_BSY) && timeout--)
 198                ;
 199}
 200
 201static void bmi_tx_port_init(struct fm_bmi_tx_port *tx_port)
 202{
 203        /* set BMI to independent mode, Tx port disable */
 204        out_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_IM);
 205        /* Tx frame next engine -RISC */
 206        out_be32(&tx_port->fmbm_tfne, NIA_ENG_RISC | NIA_RISC_AC_IM_TX);
 207        out_be32(&tx_port->fmbm_tfene, NIA_ENG_RISC | NIA_RISC_AC_IM_TX);
 208        /* Tx command attribute - no order, MR[3] = 1 */
 209        clrbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_ORDER | FMBM_TFCA_MR_MASK);
 210        setbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_MR(4));
 211        /* enable Tx statistic counters */
 212        out_be32(&tx_port->fmbm_tstc, FMBM_TSTC_EN);
 213        /* disable Tx performance counters */
 214        out_be32(&tx_port->fmbm_tpc, 0);
 215}
 216
 217static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
 218{
 219        struct fm_port_global_pram *pram;
 220        u32 pram_page_offset;
 221        void *rx_bd_ring_base;
 222        void *rx_buf_pool;
 223        u32 bd_ring_base_lo, bd_ring_base_hi;
 224        u32 buf_lo, buf_hi;
 225        struct fm_port_bd *rxbd;
 226        struct fm_port_qd *rxqd;
 227        struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port;
 228        int i;
 229
 230        /* alloc global parameter ram at MURAM */
 231        pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index,
 232                FM_PRAM_SIZE, FM_PRAM_ALIGN);
 233        if (!pram) {
 234                printf("%s: No muram for Rx global parameter\n", __func__);
 235                return -ENOMEM;
 236        }
 237
 238        fm_eth->rx_pram = pram;
 239
 240        /* parameter page offset to MURAM */
 241        pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index);
 242
 243        /* enable global mode- snooping data buffers and BDs */
 244        out_be32(&pram->mode, PRAM_MODE_GLOBAL);
 245
 246        /* init the Rx queue descriptor pionter */
 247        out_be32(&pram->rxqd_ptr, pram_page_offset + 0x20);
 248
 249        /* set the max receive buffer length, power of 2 */
 250        muram_writew(&pram->mrblr, MAX_RXBUF_LOG2);
 251
 252        /* alloc Rx buffer descriptors from main memory */
 253        rx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
 254                        * RX_BD_RING_SIZE);
 255        if (!rx_bd_ring_base)
 256                return -ENOMEM;
 257
 258        memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd)
 259                        * RX_BD_RING_SIZE);
 260
 261        /* alloc Rx buffer from main memory */
 262        rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE);
 263        if (!rx_buf_pool)
 264                return -ENOMEM;
 265
 266        memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE);
 267        debug("%s: rx_buf_pool = %p\n", __func__, rx_buf_pool);
 268
 269        /* save them to fm_eth */
 270        fm_eth->rx_bd_ring = rx_bd_ring_base;
 271        fm_eth->cur_rxbd = rx_bd_ring_base;
 272        fm_eth->rx_buf = rx_buf_pool;
 273
 274        /* init Rx BDs ring */
 275        rxbd = (struct fm_port_bd *)rx_bd_ring_base;
 276        for (i = 0; i < RX_BD_RING_SIZE; i++) {
 277                muram_writew(&rxbd->status, RxBD_EMPTY);
 278                muram_writew(&rxbd->len, 0);
 279                buf_hi = upper_32_bits(virt_to_phys(rx_buf_pool +
 280                                        i * MAX_RXBUF_LEN));
 281                buf_lo = lower_32_bits(virt_to_phys(rx_buf_pool +
 282                                        i * MAX_RXBUF_LEN));
 283                muram_writew(&rxbd->buf_ptr_hi, (u16)buf_hi);
 284                out_be32(&rxbd->buf_ptr_lo, buf_lo);
 285                rxbd++;
 286        }
 287
 288        /* set the Rx queue descriptor */
 289        rxqd = &pram->rxqd;
 290        muram_writew(&rxqd->gen, 0);
 291        bd_ring_base_hi = upper_32_bits(virt_to_phys(rx_bd_ring_base));
 292        bd_ring_base_lo = lower_32_bits(virt_to_phys(rx_bd_ring_base));
 293        muram_writew(&rxqd->bd_ring_base_hi, (u16)bd_ring_base_hi);
 294        out_be32(&rxqd->bd_ring_base_lo, bd_ring_base_lo);
 295        muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd)
 296                        * RX_BD_RING_SIZE);
 297        muram_writew(&rxqd->offset_in, 0);
 298        muram_writew(&rxqd->offset_out, 0);
 299
 300        /* set IM parameter ram pointer to Rx Frame Queue ID */
 301        out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset);
 302
 303        return 0;
 304}
 305
 306static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
 307{
 308        struct fm_port_global_pram *pram;
 309        u32 pram_page_offset;
 310        void *tx_bd_ring_base;
 311        u32 bd_ring_base_lo, bd_ring_base_hi;
 312        struct fm_port_bd *txbd;
 313        struct fm_port_qd *txqd;
 314        struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port;
 315        int i;
 316
 317        /* alloc global parameter ram at MURAM */
 318        pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index,
 319                FM_PRAM_SIZE, FM_PRAM_ALIGN);
 320        if (!pram) {
 321                printf("%s: No muram for Tx global parameter\n", __func__);
 322                return -ENOMEM;
 323        }
 324        fm_eth->tx_pram = pram;
 325
 326        /* parameter page offset to MURAM */
 327        pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index);
 328
 329        /* enable global mode- snooping data buffers and BDs */
 330        out_be32(&pram->mode, PRAM_MODE_GLOBAL);
 331
 332        /* init the Tx queue descriptor pionter */
 333        out_be32(&pram->txqd_ptr, pram_page_offset + 0x40);
 334
 335        /* alloc Tx buffer descriptors from main memory */
 336        tx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
 337                        * TX_BD_RING_SIZE);
 338        if (!tx_bd_ring_base)
 339                return -ENOMEM;
 340
 341        memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd)
 342                        * TX_BD_RING_SIZE);
 343        /* save it to fm_eth */
 344        fm_eth->tx_bd_ring = tx_bd_ring_base;
 345        fm_eth->cur_txbd = tx_bd_ring_base;
 346
 347        /* init Tx BDs ring */
 348        txbd = (struct fm_port_bd *)tx_bd_ring_base;
 349        for (i = 0; i < TX_BD_RING_SIZE; i++) {
 350                muram_writew(&txbd->status, TxBD_LAST);
 351                muram_writew(&txbd->len, 0);
 352                muram_writew(&txbd->buf_ptr_hi, 0);
 353                out_be32(&txbd->buf_ptr_lo, 0);
 354                txbd++;
 355        }
 356
 357        /* set the Tx queue decriptor */
 358        txqd = &pram->txqd;
 359        bd_ring_base_hi = upper_32_bits(virt_to_phys(tx_bd_ring_base));
 360        bd_ring_base_lo = lower_32_bits(virt_to_phys(tx_bd_ring_base));
 361        muram_writew(&txqd->bd_ring_base_hi, (u16)bd_ring_base_hi);
 362        out_be32(&txqd->bd_ring_base_lo, bd_ring_base_lo);
 363        muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd)
 364                        * TX_BD_RING_SIZE);
 365        muram_writew(&txqd->offset_in, 0);
 366        muram_writew(&txqd->offset_out, 0);
 367
 368        /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */
 369        out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset);
 370
 371        return 0;
 372}
 373
 374static int fm_eth_init(struct fm_eth *fm_eth)
 375{
 376        int ret;
 377
 378        ret = fm_eth_rx_port_parameter_init(fm_eth);
 379        if (ret)
 380                return ret;
 381
 382        ret = fm_eth_tx_port_parameter_init(fm_eth);
 383        if (ret)
 384                return ret;
 385
 386        return 0;
 387}
 388
 389static int fm_eth_startup(struct fm_eth *fm_eth)
 390{
 391        struct fsl_enet_mac *mac;
 392        int ret;
 393
 394        mac = fm_eth->mac;
 395
 396        /* Rx/TxBDs, Rx/TxQDs, Rx buff and parameter ram init */
 397        ret = fm_eth_init(fm_eth);
 398        if (ret)
 399                return ret;
 400        /* setup the MAC controller */
 401        mac->init_mac(mac);
 402
 403        /* For some reason we need to set SPEED_100 */
 404        if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) ||
 405             (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500) ||
 406             (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) &&
 407              mac->set_if_mode)
 408                mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100);
 409
 410        /* init bmi rx port, IM mode and disable */
 411        bmi_rx_port_init(fm_eth->rx_port);
 412        /* init bmi tx port, IM mode and disable */
 413        bmi_tx_port_init(fm_eth->tx_port);
 414
 415        return 0;
 416}
 417
 418static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth)
 419{
 420        struct fm_port_global_pram *pram;
 421
 422        pram = fm_eth->tx_pram;
 423        /* graceful stop transmission of frames */
 424        setbits_be32(&pram->mode, PRAM_MODE_GRACEFUL_STOP);
 425        sync();
 426}
 427
 428static void fmc_tx_port_graceful_stop_disable(struct fm_eth *fm_eth)
 429{
 430        struct fm_port_global_pram *pram;
 431
 432        pram = fm_eth->tx_pram;
 433        /* re-enable transmission of frames */
 434        clrbits_be32(&pram->mode, PRAM_MODE_GRACEFUL_STOP);
 435        sync();
 436}
 437
 438static int fm_eth_open(struct eth_device *dev, bd_t *bd)
 439{
 440        struct fm_eth *fm_eth;
 441        struct fsl_enet_mac *mac;
 442#ifdef CONFIG_PHYLIB
 443        int ret;
 444#endif
 445
 446        fm_eth = (struct fm_eth *)dev->priv;
 447        mac = fm_eth->mac;
 448
 449        /* setup the MAC address */
 450        if (dev->enetaddr[0] & 0x01) {
 451                printf("%s: MacAddress is multcast address\n",  __func__);
 452                return 1;
 453        }
 454        mac->set_mac_addr(mac, dev->enetaddr);
 455
 456        /* enable bmi Rx port */
 457        setbits_be32(&fm_eth->rx_port->fmbm_rcfg, FMBM_RCFG_EN);
 458        /* enable MAC rx/tx port */
 459        mac->enable_mac(mac);
 460        /* enable bmi Tx port */
 461        setbits_be32(&fm_eth->tx_port->fmbm_tcfg, FMBM_TCFG_EN);
 462        /* re-enable transmission of frame */
 463        fmc_tx_port_graceful_stop_disable(fm_eth);
 464
 465#ifdef CONFIG_PHYLIB
 466        if (fm_eth->phydev) {
 467                ret = phy_startup(fm_eth->phydev);
 468                if (ret) {
 469                        printf("%s: Could not initialize\n",
 470                               fm_eth->phydev->dev->name);
 471                        return ret;
 472                }
 473        } else {
 474                return 0;
 475        }
 476#else
 477        fm_eth->phydev->speed = SPEED_1000;
 478        fm_eth->phydev->link = 1;
 479        fm_eth->phydev->duplex = DUPLEX_FULL;
 480#endif
 481
 482        /* set the MAC-PHY mode */
 483        mac->set_if_mode(mac, fm_eth->enet_if, fm_eth->phydev->speed);
 484
 485        if (!fm_eth->phydev->link)
 486                printf("%s: No link.\n", fm_eth->phydev->dev->name);
 487
 488        return fm_eth->phydev->link ? 0 : -1;
 489}
 490
 491static void fm_eth_halt(struct eth_device *dev)
 492{
 493        struct fm_eth *fm_eth;
 494        struct fsl_enet_mac *mac;
 495
 496        fm_eth = (struct fm_eth *)dev->priv;
 497        mac = fm_eth->mac;
 498
 499        /* graceful stop the transmission of frames */
 500        fmc_tx_port_graceful_stop_enable(fm_eth);
 501        /* disable bmi Tx port */
 502        bmi_tx_port_disable(fm_eth->tx_port);
 503        /* disable MAC rx/tx port */
 504        mac->disable_mac(mac);
 505        /* disable bmi Rx port */
 506        bmi_rx_port_disable(fm_eth->rx_port);
 507
 508#ifdef CONFIG_PHYLIB
 509        if (fm_eth->phydev)
 510                phy_shutdown(fm_eth->phydev);
 511#endif
 512}
 513
 514static int fm_eth_send(struct eth_device *dev, void *buf, int len)
 515{
 516        struct fm_eth *fm_eth;
 517        struct fm_port_global_pram *pram;
 518        struct fm_port_bd *txbd, *txbd_base;
 519        u16 offset_in;
 520        int i;
 521
 522        fm_eth = (struct fm_eth *)dev->priv;
 523        pram = fm_eth->tx_pram;
 524        txbd = fm_eth->cur_txbd;
 525
 526        /* find one empty TxBD */
 527        for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) {
 528                udelay(100);
 529                if (i > 0x1000) {
 530                        printf("%s: Tx buffer not ready, txbd->status = 0x%x\n",
 531                               dev->name, muram_readw(&txbd->status));
 532                        return 0;
 533                }
 534        }
 535        /* setup TxBD */
 536        muram_writew(&txbd->buf_ptr_hi, (u16)upper_32_bits(virt_to_phys(buf)));
 537        out_be32(&txbd->buf_ptr_lo, lower_32_bits(virt_to_phys(buf)));
 538        muram_writew(&txbd->len, len);
 539        sync();
 540        muram_writew(&txbd->status, TxBD_READY | TxBD_LAST);
 541        sync();
 542
 543        /* update TxQD, let RISC to send the packet */
 544        offset_in = muram_readw(&pram->txqd.offset_in);
 545        offset_in += sizeof(struct fm_port_bd);
 546        if (offset_in >= muram_readw(&pram->txqd.bd_ring_size))
 547                offset_in = 0;
 548        muram_writew(&pram->txqd.offset_in, offset_in);
 549        sync();
 550
 551        /* wait for buffer to be transmitted */
 552        for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) {
 553                udelay(100);
 554                if (i > 0x10000) {
 555                        printf("%s: Tx error, txbd->status = 0x%x\n",
 556                               dev->name, muram_readw(&txbd->status));
 557                        return 0;
 558                }
 559        }
 560
 561        /* advance the TxBD */
 562        txbd++;
 563        txbd_base = (struct fm_port_bd *)fm_eth->tx_bd_ring;
 564        if (txbd >= (txbd_base + TX_BD_RING_SIZE))
 565                txbd = txbd_base;
 566        /* update current txbd */
 567        fm_eth->cur_txbd = (void *)txbd;
 568
 569        return 1;
 570}
 571
 572static int fm_eth_recv(struct eth_device *dev)
 573{
 574        struct fm_eth *fm_eth;
 575        struct fm_port_global_pram *pram;
 576        struct fm_port_bd *rxbd, *rxbd_base;
 577        u16 status, len;
 578        u32 buf_lo, buf_hi;
 579        u8 *data;
 580        u16 offset_out;
 581        int ret = 1;
 582
 583        fm_eth = (struct fm_eth *)dev->priv;
 584        pram = fm_eth->rx_pram;
 585        rxbd = fm_eth->cur_rxbd;
 586        status = muram_readw(&rxbd->status);
 587
 588        while (!(status & RxBD_EMPTY)) {
 589                if (!(status & RxBD_ERROR)) {
 590                        buf_hi = muram_readw(&rxbd->buf_ptr_hi);
 591                        buf_lo = in_be32(&rxbd->buf_ptr_lo);
 592                        data = (u8 *)((ulong)(buf_hi << 16) << 16 | buf_lo);
 593                        len = muram_readw(&rxbd->len);
 594                        net_process_received_packet(data, len);
 595                } else {
 596                        printf("%s: Rx error\n", dev->name);
 597                        ret = 0;
 598                }
 599
 600                /* clear the RxBDs */
 601                muram_writew(&rxbd->status, RxBD_EMPTY);
 602                muram_writew(&rxbd->len, 0);
 603                sync();
 604
 605                /* advance RxBD */
 606                rxbd++;
 607                rxbd_base = (struct fm_port_bd *)fm_eth->rx_bd_ring;
 608                if (rxbd >= (rxbd_base + RX_BD_RING_SIZE))
 609                        rxbd = rxbd_base;
 610                /* read next status */
 611                status = muram_readw(&rxbd->status);
 612
 613                /* update RxQD */
 614                offset_out = muram_readw(&pram->rxqd.offset_out);
 615                offset_out += sizeof(struct fm_port_bd);
 616                if (offset_out >= muram_readw(&pram->rxqd.bd_ring_size))
 617                        offset_out = 0;
 618                muram_writew(&pram->rxqd.offset_out, offset_out);
 619                sync();
 620        }
 621        fm_eth->cur_rxbd = (void *)rxbd;
 622
 623        return ret;
 624}
 625
 626static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)
 627{
 628        struct fsl_enet_mac *mac;
 629        int num;
 630        void *base, *phyregs = NULL;
 631
 632        num = fm_eth->num;
 633
 634#ifdef CONFIG_SYS_FMAN_V3
 635#ifndef CONFIG_FSL_FM_10GEC_REGULAR_NOTATION
 636        if (fm_eth->type == FM_ETH_10G_E) {
 637                /* 10GEC1/10GEC2 use mEMAC9/mEMAC10 on T2080/T4240.
 638                 * 10GEC3/10GEC4 use mEMAC1/mEMAC2 on T2080.
 639                 * 10GEC1 uses mEMAC1 on T1024.
 640                 * so it needs to change the num.
 641                 */
 642                if (fm_eth->num >= 2)
 643                        num -= 2;
 644                else
 645                        num += 8;
 646        }
 647#endif
 648        base = &reg->memac[num].fm_memac;
 649        phyregs = &reg->memac[num].fm_memac_mdio;
 650#else
 651        /* Get the mac registers base address */
 652        if (fm_eth->type == FM_ETH_1G_E) {
 653                base = &reg->mac_1g[num].fm_dtesc;
 654                phyregs = &reg->mac_1g[num].fm_mdio.miimcfg;
 655        } else {
 656                base = &reg->mac_10g[num].fm_10gec;
 657                phyregs = &reg->mac_10g[num].fm_10gec_mdio;
 658        }
 659#endif
 660
 661        /* alloc mac controller */
 662        mac = malloc(sizeof(struct fsl_enet_mac));
 663        if (!mac)
 664                return -ENOMEM;
 665        memset(mac, 0, sizeof(struct fsl_enet_mac));
 666
 667        /* save the mac to fm_eth struct */
 668        fm_eth->mac = mac;
 669
 670#ifdef CONFIG_SYS_FMAN_V3
 671        init_memac(mac, base, phyregs, MAX_RXBUF_LEN);
 672#else
 673        if (fm_eth->type == FM_ETH_1G_E)
 674                init_dtsec(mac, base, phyregs, MAX_RXBUF_LEN);
 675        else
 676                init_tgec(mac, base, phyregs, MAX_RXBUF_LEN);
 677#endif
 678
 679        return 0;
 680}
 681
 682static int init_phy(struct eth_device *dev)
 683{
 684        struct fm_eth *fm_eth = dev->priv;
 685#ifdef CONFIG_PHYLIB
 686        struct phy_device *phydev = NULL;
 687        u32 supported;
 688#endif
 689
 690        if (fm_eth->type == FM_ETH_1G_E)
 691                dtsec_init_phy(dev);
 692
 693#ifdef CONFIG_PHYLIB
 694        if (fm_eth->bus) {
 695                phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev,
 696                                        fm_eth->enet_if);
 697                if (!phydev) {
 698                        printf("Failed to connect\n");
 699                        return -1;
 700                }
 701        } else {
 702                return 0;
 703        }
 704
 705        if (fm_eth->type == FM_ETH_1G_E) {
 706                supported = (SUPPORTED_10baseT_Half |
 707                                SUPPORTED_10baseT_Full |
 708                                SUPPORTED_100baseT_Half |
 709                                SUPPORTED_100baseT_Full |
 710                                SUPPORTED_1000baseT_Full);
 711        } else {
 712                supported = SUPPORTED_10000baseT_Full;
 713
 714                if (tgec_is_fibre(dev))
 715                        phydev->port = PORT_FIBRE;
 716        }
 717
 718        phydev->supported &= supported;
 719        phydev->advertising = phydev->supported;
 720
 721        fm_eth->phydev = phydev;
 722
 723        phy_config(phydev);
 724#endif
 725
 726        return 0;
 727}
 728
 729int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
 730{
 731        struct eth_device *dev;
 732        struct fm_eth *fm_eth;
 733        int i, num = info->num;
 734        int ret;
 735
 736        /* alloc eth device */
 737        dev = (struct eth_device *)malloc(sizeof(struct eth_device));
 738        if (!dev)
 739                return -ENOMEM;
 740        memset(dev, 0, sizeof(struct eth_device));
 741
 742        /* alloc the FMan ethernet private struct */
 743        fm_eth = (struct fm_eth *)malloc(sizeof(struct fm_eth));
 744        if (!fm_eth)
 745                return -ENOMEM;
 746        memset(fm_eth, 0, sizeof(struct fm_eth));
 747
 748        /* save off some things we need from the info struct */
 749        fm_eth->fm_index = info->index - 1; /* keep as 0 based for muram */
 750        fm_eth->num = num;
 751        fm_eth->type = info->type;
 752
 753        fm_eth->rx_port = (void *)&reg->port[info->rx_port_id - 1].fm_bmi;
 754        fm_eth->tx_port = (void *)&reg->port[info->tx_port_id - 1].fm_bmi;
 755
 756        /* set the ethernet max receive length */
 757        fm_eth->max_rx_len = MAX_RXBUF_LEN;
 758
 759        /* init global mac structure */
 760        ret = fm_eth_init_mac(fm_eth, reg);
 761        if (ret)
 762                return ret;
 763
 764        /* keep same as the manual, we call FMAN1, FMAN2, DTSEC1, DTSEC2, etc */
 765        if (fm_eth->type == FM_ETH_1G_E)
 766                sprintf(dev->name, "FM%d@DTSEC%d", info->index, num + 1);
 767        else
 768                sprintf(dev->name, "FM%d@TGEC%d", info->index, num + 1);
 769
 770        devlist[num_controllers++] = dev;
 771        dev->iobase = 0;
 772        dev->priv = (void *)fm_eth;
 773        dev->init = fm_eth_open;
 774        dev->halt = fm_eth_halt;
 775        dev->send = fm_eth_send;
 776        dev->recv = fm_eth_recv;
 777        fm_eth->dev = dev;
 778        fm_eth->bus = info->bus;
 779        fm_eth->phyaddr = info->phy_addr;
 780        fm_eth->enet_if = info->enet_if;
 781
 782        /* startup the FM im */
 783        ret = fm_eth_startup(fm_eth);
 784        if (ret)
 785                return ret;
 786
 787        init_phy(dev);
 788
 789        /* clear the ethernet address */
 790        for (i = 0; i < 6; i++)
 791                dev->enetaddr[i] = 0;
 792        eth_register(dev);
 793
 794        return 0;
 795}
 796