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