uboot/drivers/net/ldpaa_eth/ldpaa_eth.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2014-2016 Freescale Semiconductor, Inc.
   4 * Copyright 2017 NXP
   5 */
   6
   7#include <common.h>
   8#include <cpu_func.h>
   9#include <dm/device_compat.h>
  10#include <fsl-mc/fsl_dpmac.h>
  11#include <fsl-mc/ldpaa_wriop.h>
  12#include <hwconfig.h>
  13#include <log.h>
  14#include <malloc.h>
  15#include <miiphy.h>
  16#include <net.h>
  17#include <phy.h>
  18#include <asm/io.h>
  19#include <asm/types.h>
  20#include <linux/bug.h>
  21#include <linux/compat.h>
  22#include <linux/delay.h>
  23#include <asm/global_data.h>
  24#include "ldpaa_eth.h"
  25
  26#ifdef CONFIG_PHYLIB
  27#ifdef CONFIG_DM_ETH
  28static void init_phy(struct udevice *dev)
  29{
  30        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
  31
  32        priv->phy = dm_eth_phy_connect(dev);
  33
  34        if (!priv->phy)
  35                return;
  36
  37        phy_config(priv->phy);
  38}
  39#else
  40static int init_phy(struct eth_device *dev)
  41{
  42        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
  43        struct phy_device *phydev = NULL;
  44        struct mii_dev *bus;
  45        int phy_addr, phy_num;
  46        int ret = 0;
  47
  48        bus = wriop_get_mdio(priv->dpmac_id);
  49        if (bus == NULL)
  50                return 0;
  51
  52        for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
  53                phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num);
  54                if (phy_addr < 0)
  55                        continue;
  56
  57                phydev = phy_connect(bus, phy_addr, dev,
  58                                     wriop_get_enet_if(priv->dpmac_id));
  59                if (!phydev) {
  60                        printf("Failed to connect\n");
  61                        ret = -ENODEV;
  62                        break;
  63                }
  64                wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev);
  65                ret = phy_config(phydev);
  66                if (ret)
  67                        break;
  68        }
  69
  70        if (ret) {
  71                for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
  72                        phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
  73                        if (!phydev)
  74                                continue;
  75
  76                        free(phydev);
  77                        wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL);
  78                }
  79        }
  80
  81        return ret;
  82}
  83#endif
  84#endif
  85
  86#ifdef DEBUG
  87
  88#define DPNI_STATS_PER_PAGE 6
  89
  90static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = {
  91        {
  92        "DPNI_CNT_ING_ALL_FRAMES",
  93        "DPNI_CNT_ING_ALL_BYTES",
  94        "DPNI_CNT_ING_MCAST_FRAMES",
  95        "DPNI_CNT_ING_MCAST_BYTES",
  96        "DPNI_CNT_ING_BCAST_FRAMES",
  97        "DPNI_CNT_ING_BCAST_BYTES",
  98        }, {
  99        "DPNI_CNT_EGR_ALL_FRAMES",
 100        "DPNI_CNT_EGR_ALL_BYTES",
 101        "DPNI_CNT_EGR_MCAST_FRAMES",
 102        "DPNI_CNT_EGR_MCAST_BYTES",
 103        "DPNI_CNT_EGR_BCAST_FRAMES",
 104        "DPNI_CNT_EGR_BCAST_BYTES",
 105        }, {
 106        "DPNI_CNT_ING_FILTERED_FRAMES",
 107        "DPNI_CNT_ING_DISCARDED_FRAMES",
 108        "DPNI_CNT_ING_NOBUFFER_DISCARDS",
 109        "DPNI_CNT_EGR_DISCARDED_FRAMES",
 110        "DPNI_CNT_EGR_CNF_FRAMES",
 111        ""
 112        },
 113};
 114
 115static void print_dpni_stats(const char *strings[],
 116                             struct dpni_statistics dpni_stats)
 117{
 118        uint64_t *stat;
 119        int i;
 120
 121        stat = (uint64_t *)&dpni_stats;
 122        for (i = 0; i < DPNI_STATS_PER_PAGE; i++) {
 123                if (strcmp(strings[i], "\0") == 0)
 124                        break;
 125                printf("%s= %llu\n", strings[i], *stat);
 126                stat++;
 127        }
 128}
 129
 130static void ldpaa_eth_get_dpni_counter(void)
 131{
 132        int err = 0;
 133        unsigned int page = 0;
 134        struct dpni_statistics dpni_stats;
 135
 136        printf("DPNI counters ..\n");
 137        for (page = 0; page < 3; page++) {
 138                err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS,
 139                                          dflt_dpni->dpni_handle, page,
 140                                          &dpni_stats);
 141                if (err < 0) {
 142                        printf("dpni_get_statistics: failed:");
 143                        printf("%d for page[%d]\n", err, page);
 144                        return;
 145                }
 146                print_dpni_stats(dpni_statistics[page], dpni_stats);
 147        }
 148}
 149
 150#ifdef CONFIG_DM_ETH
 151static void ldpaa_eth_get_dpmac_counter(struct udevice *dev)
 152{
 153        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
 154#else
 155static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
 156{
 157        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 158#endif
 159        int err = 0;
 160        u64 value;
 161
 162        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 163                     priv->dpmac_handle,
 164                     DPMAC_CNT_ING_BYTE,
 165                     &value);
 166        if (err < 0) {
 167                printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
 168                return;
 169        }
 170        printf("\nDPMAC counters ..\n");
 171        printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
 172
 173        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 174                     priv->dpmac_handle,
 175                     DPMAC_CNT_ING_FRAME_DISCARD,
 176                     &value);
 177        if (err < 0) {
 178                printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
 179                return;
 180        }
 181        printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
 182
 183        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 184                     priv->dpmac_handle,
 185                     DPMAC_CNT_ING_ALIGN_ERR,
 186                     &value);
 187        if (err < 0) {
 188                printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
 189                return;
 190        }
 191        printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
 192
 193        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 194                     priv->dpmac_handle,
 195                     DPMAC_CNT_ING_BYTE,
 196                     &value);
 197        if (err < 0) {
 198                printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
 199                return;
 200        }
 201        printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
 202
 203        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 204                     priv->dpmac_handle,
 205                     DPMAC_CNT_ING_ERR_FRAME,
 206                     &value);
 207        if (err < 0) {
 208                printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
 209                return;
 210        }
 211        printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
 212
 213        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 214                     priv->dpmac_handle,
 215                     DPMAC_CNT_EGR_BYTE ,
 216                     &value);
 217        if (err < 0) {
 218                printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
 219                return;
 220        }
 221        printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
 222
 223        err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
 224                     priv->dpmac_handle,
 225                     DPMAC_CNT_EGR_ERR_FRAME ,
 226                     &value);
 227        if (err < 0) {
 228                printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
 229                return;
 230        }
 231        printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
 232}
 233#endif
 234
 235static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
 236                         const struct dpaa_fd *fd)
 237{
 238        u64 fd_addr;
 239        uint16_t fd_offset;
 240        uint32_t fd_length;
 241        struct ldpaa_fas *fas;
 242        uint32_t status, err;
 243        u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
 244        u32 time_start;
 245        struct qbman_release_desc releasedesc;
 246        struct qbman_swp *swp = dflt_dpio->sw_portal;
 247
 248        fd_addr = ldpaa_fd_get_addr(fd);
 249        fd_offset = ldpaa_fd_get_offset(fd);
 250        fd_length = ldpaa_fd_get_len(fd);
 251
 252        debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
 253
 254        if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
 255                /* Read the frame annotation status word and check for errors */
 256                fas = (struct ldpaa_fas *)
 257                                ((uint8_t *)(fd_addr) +
 258                                dflt_dpni->buf_layout.private_data_size);
 259                status = le32_to_cpu(fas->status);
 260                if (status & LDPAA_ETH_RX_ERR_MASK) {
 261                        printf("Rx frame error(s): 0x%08x\n",
 262                               status & LDPAA_ETH_RX_ERR_MASK);
 263                        goto error;
 264                } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
 265                        printf("Unsupported feature in bitmask: 0x%08x\n",
 266                               status & LDPAA_ETH_RX_UNSUPP_MASK);
 267                        goto error;
 268                }
 269        }
 270
 271        debug("Rx frame: To Upper layer\n");
 272        net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
 273                                    fd_length);
 274
 275error:
 276        flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
 277        qbman_release_desc_clear(&releasedesc);
 278        qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
 279        time_start = get_timer(0);
 280        do {
 281                /* Release buffer into the QBMAN */
 282                err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
 283        } while (get_timer(time_start) < timeo && err == -EBUSY);
 284
 285        if (err == -EBUSY)
 286                printf("Rx frame: QBMAN buffer release fails\n");
 287
 288        return;
 289}
 290
 291#ifdef CONFIG_DM_ETH
 292static int ldpaa_eth_pull_dequeue_rx(struct udevice *dev,
 293                                     int flags, uchar **packetp)
 294{
 295        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
 296#else
 297static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
 298{
 299        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
 300#endif
 301        const struct ldpaa_dq *dq;
 302        const struct dpaa_fd *fd;
 303        int i = 5, err = 0, status;
 304        u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
 305        u32 time_start;
 306        static struct qbman_pull_desc pulldesc;
 307        struct qbman_swp *swp = dflt_dpio->sw_portal;
 308
 309        while (--i) {
 310                qbman_pull_desc_clear(&pulldesc);
 311                qbman_pull_desc_set_numframes(&pulldesc, 1);
 312                qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
 313
 314                err = qbman_swp_pull(swp, &pulldesc);
 315                if (err < 0) {
 316                        printf("Dequeue frames error:0x%08x\n", err);
 317                        continue;
 318                }
 319
 320                time_start = get_timer(0);
 321
 322                 do {
 323                        dq = qbman_swp_dqrr_next(swp);
 324                } while (get_timer(time_start) < timeo && !dq);
 325
 326                if (dq) {
 327                        /* Check for valid frame. If not sent a consume
 328                         * confirmation to QBMAN otherwise give it to NADK
 329                         * application and then send consume confirmation to
 330                         * QBMAN.
 331                         */
 332                        status = (uint8_t)ldpaa_dq_flags(dq);
 333                        if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
 334                                debug("Dequeue RX frames:");
 335                                debug("No frame delivered\n");
 336
 337                                qbman_swp_dqrr_consume(swp, dq);
 338                                continue;
 339                        }
 340
 341                        fd = ldpaa_dq_fd(dq);
 342
 343                        /* Obtain FD and process it */
 344                        ldpaa_eth_rx(priv, fd);
 345                        qbman_swp_dqrr_consume(swp, dq);
 346                        break;
 347                } else {
 348                        err = -ENODATA;
 349                        debug("No DQRR entries\n");
 350                        break;
 351                }
 352        }
 353
 354        return err;
 355}
 356
 357#ifdef CONFIG_DM_ETH
 358static int ldpaa_eth_tx(struct udevice *dev, void *buf, int len)
 359{
 360        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
 361#else
 362static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
 363{
 364        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 365#endif
 366        struct dpaa_fd fd;
 367        u64 buffer_start;
 368        int data_offset, err;
 369        u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
 370        u32 time_start;
 371        struct qbman_swp *swp = dflt_dpio->sw_portal;
 372        struct qbman_eq_desc ed;
 373        struct qbman_release_desc releasedesc;
 374
 375        /* Setup the FD fields */
 376        memset(&fd, 0, sizeof(fd));
 377
 378        data_offset = priv->tx_data_offset;
 379
 380        do {
 381                err = qbman_swp_acquire(dflt_dpio->sw_portal,
 382                                        dflt_dpbp->dpbp_attr.bpid,
 383                                        &buffer_start, 1);
 384        } while (err == -EBUSY);
 385
 386        if (err <= 0) {
 387                printf("qbman_swp_acquire() failed\n");
 388                return -ENOMEM;
 389        }
 390
 391        debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
 392
 393        memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
 394
 395        flush_dcache_range(buffer_start, buffer_start +
 396                                        LDPAA_ETH_RX_BUFFER_SIZE);
 397
 398        ldpaa_fd_set_addr(&fd, (u64)buffer_start);
 399        ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
 400        ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
 401        ldpaa_fd_set_len(&fd, len);
 402
 403        fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
 404                                LDPAA_FD_CTRL_PTV1;
 405
 406        qbman_eq_desc_clear(&ed);
 407        qbman_eq_desc_set_no_orp(&ed, 0);
 408        qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
 409
 410        time_start = get_timer(0);
 411
 412        while (get_timer(time_start) < timeo) {
 413                err = qbman_swp_enqueue(swp, &ed,
 414                                (const struct qbman_fd *)(&fd));
 415                if (err != -EBUSY)
 416                        break;
 417        }
 418
 419        if (err < 0) {
 420                printf("error enqueueing Tx frame\n");
 421                goto error;
 422        }
 423
 424        return err;
 425
 426error:
 427        qbman_release_desc_clear(&releasedesc);
 428        qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
 429        time_start = get_timer(0);
 430        do {
 431                /* Release buffer into the QBMAN */
 432                err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
 433        } while (get_timer(time_start) < timeo && err == -EBUSY);
 434
 435        if (err == -EBUSY)
 436                printf("TX data: QBMAN buffer release fails\n");
 437
 438        return err;
 439}
 440
 441static struct phy_device *ldpaa_get_phydev(struct ldpaa_eth_priv *priv)
 442{
 443#ifdef CONFIG_DM_ETH
 444        return priv->phy;
 445#else
 446#ifdef CONFIG_PHYLIB
 447        struct phy_device *phydev = NULL;
 448        int phy_num;
 449
 450        /* start the phy devices one by one and update the dpmac state */
 451        for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
 452                phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
 453                if (phydev)
 454                        return phydev;
 455        }
 456        return NULL;
 457#endif
 458        return NULL;
 459#endif
 460}
 461
 462static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
 463                                 struct dpmac_link_state *state)
 464{
 465        phy_interface_t enet_if;
 466        struct phy_device *phydev = NULL;
 467        int err;
 468
 469        /* let's start off with maximum capabilities */
 470        enet_if = wriop_get_enet_if(priv->dpmac_id);
 471        switch (enet_if) {
 472        case PHY_INTERFACE_MODE_XGMII:
 473                state->rate = SPEED_10000;
 474                break;
 475        default:
 476                state->rate = SPEED_1000;
 477                break;
 478        }
 479
 480        state->up = 1;
 481        state->options |= DPMAC_LINK_OPT_AUTONEG;
 482        phydev = ldpaa_get_phydev(priv);
 483
 484        if (phydev) {
 485                err = phy_startup(phydev);
 486                if (err) {
 487                        printf("%s: Could not initialize\n", phydev->dev->name);
 488                        state->up = 0;
 489                } else if (phydev->link) {
 490                        state->rate = min(state->rate, (uint32_t)phydev->speed);
 491                        if (!phydev->duplex)
 492                                state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
 493                        if (!phydev->autoneg)
 494                                state->options &= ~DPMAC_LINK_OPT_AUTONEG;
 495                } else {
 496                        state->up = 0;
 497                }
 498        }
 499
 500        if (!phydev)
 501                state->options &= ~DPMAC_LINK_OPT_AUTONEG;
 502
 503        if (!state->up) {
 504                state->rate = 0;
 505                state->options = 0;
 506                return -ENOLINK;
 507        }
 508
 509        return 0;
 510}
 511
 512#ifdef CONFIG_DM_ETH
 513static int ldpaa_eth_open(struct udevice *dev)
 514{
 515        struct eth_pdata *plat = dev_get_plat(dev);
 516        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
 517#else
 518static int ldpaa_eth_open(struct eth_device *net_dev, struct bd_info *bd)
 519{
 520        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 521#endif
 522        struct dpmac_link_state dpmac_link_state = { 0 };
 523#ifdef DEBUG
 524        struct dpni_link_state link_state;
 525#endif
 526        int err = 0;
 527        struct dpni_queue d_queue;
 528
 529#ifdef CONFIG_DM_ETH
 530        if (eth_is_active(dev))
 531                return 0;
 532#else
 533        if (net_dev->state == ETH_STATE_ACTIVE)
 534                return 0;
 535#endif
 536
 537        if (get_mc_boot_status() != 0) {
 538                printf("ERROR (MC is not booted)\n");
 539                return -ENODEV;
 540        }
 541
 542        if (get_dpl_apply_status() == 0) {
 543                printf("ERROR (DPL is deployed. No device available)\n");
 544                return -ENODEV;
 545        }
 546
 547        /* DPMAC initialization */
 548        err = ldpaa_dpmac_setup(priv);
 549        if (err < 0)
 550                goto err_dpmac_setup;
 551
 552        err = ldpaa_get_dpmac_state(priv, &dpmac_link_state);
 553        if (err < 0)
 554                goto err_dpmac_bind;
 555
 556        /* DPMAC binding DPNI */
 557        err = ldpaa_dpmac_bind(priv);
 558        if (err)
 559                goto err_dpmac_bind;
 560
 561        /* DPNI initialization */
 562        err = ldpaa_dpni_setup(priv);
 563        if (err < 0)
 564                goto err_dpni_setup;
 565
 566        err = ldpaa_dpbp_setup();
 567        if (err < 0)
 568                goto err_dpbp_setup;
 569
 570        /* DPNI binding DPBP */
 571        err = ldpaa_dpni_bind(priv);
 572        if (err)
 573                goto err_dpni_bind;
 574
 575#ifdef CONFIG_DM_ETH
 576        err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
 577                                dflt_dpni->dpni_handle, plat->enetaddr);
 578#else
 579        err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
 580                                dflt_dpni->dpni_handle, net_dev->enetaddr);
 581#endif
 582        if (err) {
 583                printf("dpni_add_mac_addr() failed\n");
 584                return err;
 585        }
 586
 587        err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 588        if (err < 0) {
 589                printf("dpni_enable() failed\n");
 590                return err;
 591        }
 592
 593        err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
 594                                  priv->dpmac_handle, &dpmac_link_state);
 595        if (err < 0) {
 596                printf("dpmac_set_link_state() failed\n");
 597                return err;
 598        }
 599
 600#ifdef DEBUG
 601        printf("DPMAC link status: %d - ", dpmac_link_state.up);
 602        dpmac_link_state.up == 0 ? printf("down\n") :
 603        dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n");
 604
 605        err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
 606                                  dflt_dpni->dpni_handle, &link_state);
 607        if (err < 0) {
 608                printf("dpni_get_link_state() failed\n");
 609                return err;
 610        }
 611
 612        printf("DPNI link status: %d - ", link_state.up);
 613        link_state.up == 0 ? printf("down\n") :
 614        link_state.up == 1 ? printf("up\n") : printf("error state\n");
 615#endif
 616
 617        memset(&d_queue, 0, sizeof(struct dpni_queue));
 618        err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
 619                             dflt_dpni->dpni_handle, DPNI_QUEUE_RX,
 620                             0, 0, &d_queue);
 621        if (err) {
 622                printf("dpni_get_queue failed\n");
 623                goto err_get_queue;
 624        }
 625
 626        priv->rx_dflt_fqid = d_queue.fqid;
 627
 628        err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
 629                            &priv->tx_qdid);
 630        if (err) {
 631                printf("dpni_get_qdid() failed\n");
 632                goto err_qdid;
 633        }
 634
 635        return dpmac_link_state.up;
 636
 637err_qdid:
 638err_get_queue:
 639        dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 640err_dpni_bind:
 641        ldpaa_dpbp_free();
 642err_dpbp_setup:
 643        dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 644err_dpni_setup:
 645err_dpmac_bind:
 646        dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
 647        dpmac_destroy(dflt_mc_io,
 648                      dflt_dprc_handle,
 649                      MC_CMD_NO_FLAGS, priv->dpmac_id);
 650err_dpmac_setup:
 651        return err;
 652}
 653
 654#ifdef CONFIG_DM_ETH
 655static void ldpaa_eth_stop(struct udevice *dev)
 656{
 657        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
 658#else
 659static void ldpaa_eth_stop(struct eth_device *net_dev)
 660{
 661        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 662#endif
 663        struct phy_device *phydev = NULL;
 664        int err = 0;
 665
 666#ifdef CONFIG_DM_ETH
 667        if (!eth_is_active(dev))
 668                return;
 669#else
 670        if ((net_dev->state == ETH_STATE_PASSIVE) ||
 671            (net_dev->state == ETH_STATE_INIT))
 672                return;
 673#endif
 674
 675#ifdef DEBUG
 676        ldpaa_eth_get_dpni_counter();
 677#ifdef CONFIG_DM_ETH
 678        ldpaa_eth_get_dpmac_counter(dev);
 679#else
 680        ldpaa_eth_get_dpmac_counter(net_dev);
 681#endif
 682#endif
 683
 684        err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
 685                              dflt_dprc_handle, &dpmac_endpoint);
 686        if (err < 0)
 687                printf("dprc_disconnect() failed dpmac_endpoint\n");
 688
 689        err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
 690        if (err < 0)
 691                printf("dpmac_close() failed\n");
 692
 693        err = dpmac_destroy(dflt_mc_io,
 694                            dflt_dprc_handle,
 695                            MC_CMD_NO_FLAGS,
 696                            priv->dpmac_id);
 697        if (err < 0)
 698                printf("dpmac_destroy() failed\n");
 699
 700        /* Stop Tx and Rx traffic */
 701        err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 702        if (err < 0)
 703                printf("dpni_disable() failed\n");
 704
 705        phydev = ldpaa_get_phydev(priv);
 706        if (phydev)
 707                phy_shutdown(phydev);
 708
 709        /* Free DPBP handle and reset. */
 710        ldpaa_dpbp_free();
 711
 712        dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 713        if (err < 0)
 714                printf("dpni_reset() failed\n");
 715
 716        dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
 717        if (err < 0)
 718                printf("dpni_close() failed\n");
 719}
 720
 721static void ldpaa_dpbp_drain_cnt(int count)
 722{
 723        uint64_t buf_array[7];
 724        void *addr;
 725        int ret, i;
 726
 727        BUG_ON(count > 7);
 728
 729        do {
 730                ret = qbman_swp_acquire(dflt_dpio->sw_portal,
 731                                        dflt_dpbp->dpbp_attr.bpid,
 732                                        buf_array, count);
 733                if (ret < 0) {
 734                        printf("qbman_swp_acquire() failed\n");
 735                        return;
 736                }
 737                for (i = 0; i < ret; i++) {
 738                        addr = (void *)buf_array[i];
 739                        debug("Free: buffer addr =0x%p\n", addr);
 740                        free(addr);
 741                }
 742        } while (ret);
 743}
 744
 745static void ldpaa_dpbp_drain(void)
 746{
 747        int i;
 748        for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
 749                ldpaa_dpbp_drain_cnt(7);
 750}
 751
 752static int ldpaa_bp_add_7(uint16_t bpid)
 753{
 754        uint64_t buf_array[7];
 755        u8 *addr;
 756        int i;
 757        struct qbman_release_desc rd;
 758
 759        for (i = 0; i < 7; i++) {
 760                addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
 761                if (!addr) {
 762                        printf("addr allocation failed\n");
 763                        goto err_alloc;
 764                }
 765                memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
 766                flush_dcache_range((u64)addr,
 767                                   (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
 768
 769                buf_array[i] = (uint64_t)addr;
 770                debug("Release: buffer addr =0x%p\n", addr);
 771        }
 772
 773release_bufs:
 774        /* In case the portal is busy, retry until successful.
 775         * This function is guaranteed to succeed in a reasonable amount
 776         * of time.
 777         */
 778
 779        do {
 780                mdelay(1);
 781                qbman_release_desc_clear(&rd);
 782                qbman_release_desc_set_bpid(&rd, bpid);
 783        } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
 784
 785        return i;
 786
 787err_alloc:
 788        if (i)
 789                goto release_bufs;
 790
 791        return 0;
 792}
 793
 794static int ldpaa_dpbp_seed(uint16_t bpid)
 795{
 796        int i;
 797        int count;
 798
 799        for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
 800                count = ldpaa_bp_add_7(bpid);
 801                if (count < 7)
 802                        printf("Buffer Seed= %d\n", count);
 803        }
 804
 805        return 0;
 806}
 807
 808static int ldpaa_dpbp_setup(void)
 809{
 810        int err;
 811
 812        err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
 813                        &dflt_dpbp->dpbp_handle);
 814        if (err) {
 815                printf("dpbp_open() failed\n");
 816                goto err_open;
 817        }
 818
 819        err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
 820        if (err) {
 821                printf("dpbp_enable() failed\n");
 822                goto err_enable;
 823        }
 824
 825        err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
 826                                  dflt_dpbp->dpbp_handle,
 827                                  &dflt_dpbp->dpbp_attr);
 828        if (err) {
 829                printf("dpbp_get_attributes() failed\n");
 830                goto err_get_attr;
 831        }
 832
 833        err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
 834
 835        if (err) {
 836                printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
 837                       dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
 838                goto err_seed;
 839        }
 840
 841        return 0;
 842
 843err_seed:
 844err_get_attr:
 845        dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
 846err_enable:
 847        dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
 848err_open:
 849        return err;
 850}
 851
 852static void ldpaa_dpbp_free(void)
 853{
 854        ldpaa_dpbp_drain();
 855        dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
 856        dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
 857        dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
 858}
 859
 860static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
 861                                     struct ldpaa_eth_priv *priv)
 862{
 863        int error;
 864        uint16_t major_ver, minor_ver;
 865
 866        error = dpmac_get_api_version(dflt_mc_io, 0,
 867                                        &major_ver,
 868                                        &minor_ver);
 869        if ((major_ver < DPMAC_VER_MAJOR) ||
 870            (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) {
 871                printf("DPMAC version mismatch found %u.%u,",
 872                       major_ver, minor_ver);
 873                printf("supported version is %u.%u\n",
 874                       DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
 875                return error;
 876        }
 877
 878        return error;
 879}
 880
 881static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
 882{
 883        int err = 0;
 884        struct dpmac_cfg dpmac_cfg;
 885
 886        dpmac_cfg.mac_id = priv->dpmac_id;
 887
 888        err = dpmac_create(dflt_mc_io,
 889                           dflt_dprc_handle,
 890                           MC_CMD_NO_FLAGS, &dpmac_cfg,
 891                           &priv->dpmac_id);
 892        if (err)
 893                printf("dpmac_create() failed\n");
 894
 895        err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
 896        if (err < 0) {
 897                printf("ldpaa_dpmac_version_check() failed: %d\n", err);
 898                goto err_version_check;
 899        }
 900
 901        err = dpmac_open(dflt_mc_io,
 902                         MC_CMD_NO_FLAGS,
 903                         priv->dpmac_id,
 904                         &priv->dpmac_handle);
 905        if (err < 0) {
 906                printf("dpmac_open() failed: %d\n", err);
 907                goto err_open;
 908        }
 909
 910        return err;
 911
 912err_open:
 913err_version_check:
 914        dpmac_destroy(dflt_mc_io,
 915                      dflt_dprc_handle,
 916                      MC_CMD_NO_FLAGS, priv->dpmac_id);
 917
 918        return err;
 919}
 920
 921static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
 922{
 923        int err = 0;
 924        struct dprc_connection_cfg dprc_connection_cfg = {
 925                /* If both rates are zero the connection */
 926                /* will be configured in "best effort" mode. */
 927                .committed_rate = 0,
 928                .max_rate = 0
 929        };
 930
 931#ifdef DEBUG
 932        struct dprc_endpoint dbg_endpoint;
 933        int state = 0;
 934#endif
 935
 936        memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
 937        strcpy(dpmac_endpoint.type, "dpmac");
 938        dpmac_endpoint.id = priv->dpmac_id;
 939
 940        memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
 941        strcpy(dpni_endpoint.type, "dpni");
 942        dpni_endpoint.id = dflt_dpni->dpni_id;
 943
 944        err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
 945                             dflt_dprc_handle,
 946                             &dpmac_endpoint,
 947                             &dpni_endpoint,
 948                             &dprc_connection_cfg);
 949        if (err)
 950                printf("dprc_connect() failed\n");
 951
 952#ifdef DEBUG
 953        err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
 954                                    dflt_dprc_handle, &dpni_endpoint,
 955                                    &dbg_endpoint, &state);
 956        printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
 957        printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
 958        printf("%s, DPMAC State= %d\n", __func__, state);
 959
 960        memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
 961        err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
 962                                    dflt_dprc_handle, &dpmac_endpoint,
 963                                    &dbg_endpoint, &state);
 964        printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
 965        printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
 966        printf("%s, DPNI State= %d\n", __func__, state);
 967#endif
 968        return err;
 969}
 970
 971static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
 972{
 973        int err;
 974
 975        /* and get a handle for the DPNI this interface is associate with */
 976        err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
 977                        &dflt_dpni->dpni_handle);
 978        if (err) {
 979                printf("dpni_open() failed\n");
 980                goto err_open;
 981        }
 982        err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
 983                                  dflt_dpni->dpni_handle,
 984                                  &dflt_dpni->dpni_attrs);
 985        if (err) {
 986                printf("dpni_get_attributes() failed (err=%d)\n", err);
 987                goto err_get_attr;
 988        }
 989
 990        /* Configure our buffers' layout */
 991        dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
 992                                   DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
 993                                   DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
 994                                   DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
 995        dflt_dpni->buf_layout.pass_parser_result = true;
 996        dflt_dpni->buf_layout.pass_frame_status = true;
 997        dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
 998        /* HW erratum mandates data alignment in multiples of 256 */
 999        dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
1000
1001        /* ...rx, ... */
1002        err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
1003                                     dflt_dpni->dpni_handle,
1004                                     &dflt_dpni->buf_layout, DPNI_QUEUE_RX);
1005        if (err) {
1006                printf("dpni_set_buffer_layout() failed");
1007                goto err_buf_layout;
1008        }
1009
1010        /* ... tx, ... */
1011        /* remove Rx-only options */
1012        dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
1013                                      DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
1014        err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
1015                                     dflt_dpni->dpni_handle,
1016                                     &dflt_dpni->buf_layout, DPNI_QUEUE_TX);
1017        if (err) {
1018                printf("dpni_set_buffer_layout() failed");
1019                goto err_buf_layout;
1020        }
1021
1022        /* ... tx-confirm. */
1023        dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
1024        err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
1025                                     dflt_dpni->dpni_handle,
1026                                     &dflt_dpni->buf_layout,
1027                                     DPNI_QUEUE_TX_CONFIRM);
1028        if (err) {
1029                printf("dpni_set_buffer_layout() failed");
1030                goto err_buf_layout;
1031        }
1032
1033        /* Now that we've set our tx buffer layout, retrieve the minimum
1034         * required tx data offset.
1035         */
1036        err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
1037                                      dflt_dpni->dpni_handle,
1038                                      &priv->tx_data_offset);
1039        if (err) {
1040                printf("dpni_get_tx_data_offset() failed\n");
1041                goto err_data_offset;
1042        }
1043
1044        /* Warn in case TX data offset is not multiple of 64 bytes. */
1045        WARN_ON(priv->tx_data_offset % 64);
1046
1047        /* Accomodate SWA space. */
1048        priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
1049        debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
1050
1051        return 0;
1052
1053err_data_offset:
1054err_buf_layout:
1055err_get_attr:
1056        dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
1057err_open:
1058        return err;
1059}
1060
1061static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
1062{
1063        struct dpni_pools_cfg pools_params;
1064        struct dpni_queue tx_queue;
1065        int err = 0;
1066
1067        memset(&pools_params, 0, sizeof(pools_params));
1068        pools_params.num_dpbp = 1;
1069        pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
1070        pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
1071        err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
1072                             dflt_dpni->dpni_handle, &pools_params);
1073        if (err) {
1074                printf("dpni_set_pools() failed\n");
1075                return err;
1076        }
1077
1078        memset(&tx_queue, 0, sizeof(struct dpni_queue));
1079
1080        err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
1081                             dflt_dpni->dpni_handle,
1082                             DPNI_QUEUE_TX, 0, 0, &tx_queue);
1083
1084        if (err) {
1085                printf("dpni_set_queue() failed\n");
1086                return err;
1087        }
1088
1089        err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS,
1090                                            dflt_dpni->dpni_handle,
1091                                            DPNI_CONF_DISABLE);
1092        if (err) {
1093                printf("dpni_set_tx_confirmation_mode() failed\n");
1094                return err;
1095        }
1096
1097        return 0;
1098}
1099
1100#ifdef CONFIG_DM_ETH
1101static int ldpaa_eth_probe(struct udevice *dev)
1102{
1103        struct ofnode_phandle_args phandle;
1104
1105        /* Nothing to do if there is no "phy-handle" in the DTS node */
1106        if (dev_read_phandle_with_args(dev, "phy-handle", NULL,
1107                                       0, 0, &phandle)) {
1108                return 0;
1109        }
1110
1111        init_phy(dev);
1112
1113        return 0;
1114}
1115
1116static uint32_t ldpaa_eth_get_dpmac_id(struct udevice *dev)
1117{
1118        int port_node = dev_of_offset(dev);
1119
1120        return fdtdec_get_uint(gd->fdt_blob, port_node, "reg", -1);
1121}
1122
1123static const char *ldpaa_eth_get_phy_mode_str(struct udevice *dev)
1124{
1125        int port_node = dev_of_offset(dev);
1126        const char *phy_mode_str;
1127
1128        phy_mode_str = fdt_getprop(gd->fdt_blob, port_node,
1129                                   "phy-connection-type", NULL);
1130        if (phy_mode_str)
1131                return phy_mode_str;
1132
1133        phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL);
1134        return phy_mode_str;
1135}
1136
1137static int ldpaa_eth_bind(struct udevice *dev)
1138{
1139        const char *phy_mode_str = NULL;
1140        uint32_t dpmac_id;
1141        char eth_name[16];
1142        int phy_mode = -1;
1143
1144        phy_mode_str = ldpaa_eth_get_phy_mode_str(dev);
1145        if (phy_mode_str)
1146                phy_mode = phy_get_interface_by_name(phy_mode_str);
1147        if (phy_mode == -1) {
1148                dev_err(dev, "incorrect phy mode\n");
1149                return -EINVAL;
1150        }
1151
1152        dpmac_id = ldpaa_eth_get_dpmac_id(dev);
1153        if (dpmac_id == -1) {
1154                dev_err(dev, "missing reg field from the dpmac node\n");
1155                return -EINVAL;
1156        }
1157
1158        sprintf(eth_name, "DPMAC%d@%s", dpmac_id, phy_mode_str);
1159        device_set_name(dev, eth_name);
1160
1161        return 0;
1162}
1163
1164static int ldpaa_eth_of_to_plat(struct udevice *dev)
1165{
1166        struct ldpaa_eth_priv *priv = dev_get_priv(dev);
1167        const char *phy_mode_str;
1168
1169        priv->dpmac_id = ldpaa_eth_get_dpmac_id(dev);
1170        phy_mode_str = ldpaa_eth_get_phy_mode_str(dev);
1171        priv->phy_mode = phy_get_interface_by_name(phy_mode_str);
1172
1173        return 0;
1174}
1175
1176static const struct eth_ops ldpaa_eth_ops = {
1177        .start  = ldpaa_eth_open,
1178        .send   = ldpaa_eth_tx,
1179        .recv   = ldpaa_eth_pull_dequeue_rx,
1180        .stop   = ldpaa_eth_stop,
1181};
1182
1183static const struct udevice_id ldpaa_eth_of_ids[] = {
1184        { .compatible = "fsl,qoriq-mc-dpmac" },
1185};
1186
1187U_BOOT_DRIVER(ldpaa_eth) = {
1188        .name = "ldpaa_eth",
1189        .id = UCLASS_ETH,
1190        .of_match = ldpaa_eth_of_ids,
1191        .of_to_plat = ldpaa_eth_of_to_plat,
1192        .bind = ldpaa_eth_bind,
1193        .probe = ldpaa_eth_probe,
1194        .ops = &ldpaa_eth_ops,
1195        .priv_auto      = sizeof(struct ldpaa_eth_priv),
1196        .plat_auto      = sizeof(struct eth_pdata),
1197};
1198
1199#else
1200
1201static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
1202                                 phy_interface_t enet_if)
1203{
1204        int err;
1205        struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
1206
1207        snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id,
1208                 phy_interface_strings[enet_if]);
1209
1210        net_dev->iobase = 0;
1211        net_dev->init = ldpaa_eth_open;
1212        net_dev->halt = ldpaa_eth_stop;
1213        net_dev->send = ldpaa_eth_tx;
1214        net_dev->recv = ldpaa_eth_pull_dequeue_rx;
1215
1216#ifdef CONFIG_PHYLIB
1217        err = init_phy(net_dev);
1218        if (err < 0)
1219                return err;
1220#endif
1221
1222        err = eth_register(net_dev);
1223        if (err < 0) {
1224                printf("eth_register() = %d\n", err);
1225                return err;
1226        }
1227
1228        return 0;
1229}
1230
1231int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
1232{
1233        struct eth_device               *net_dev = NULL;
1234        struct ldpaa_eth_priv           *priv = NULL;
1235        int                             err = 0;
1236
1237        /* Net device */
1238        net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1239        if (!net_dev) {
1240                printf("eth_device malloc() failed\n");
1241                return -ENOMEM;
1242        }
1243        memset(net_dev, 0, sizeof(struct eth_device));
1244
1245        /* alloc the ldpaa ethernet private struct */
1246        priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1247        if (!priv) {
1248                printf("ldpaa_eth_priv malloc() failed\n");
1249                free(net_dev);
1250                return -ENOMEM;
1251        }
1252        memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1253
1254        net_dev->priv = (void *)priv;
1255        priv->net_dev = (struct eth_device *)net_dev;
1256        priv->dpmac_id = dpmac_id;
1257        debug("%s dpmac_id=%d\n", __func__, dpmac_id);
1258
1259        err = ldpaa_eth_netdev_init(net_dev, enet_if);
1260        if (err)
1261                goto err_netdev_init;
1262
1263        debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1264        return 0;
1265
1266err_netdev_init:
1267        free(priv);
1268        net_dev->priv = NULL;
1269        free(net_dev);
1270
1271        return err;
1272}
1273#endif
1274