1 /* 2 * Copyright (C) 2014 Freescale Semiconductor 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 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 "ldpaa_eth.h" 18 19 #undef CONFIG_PHYLIB 20 static int init_phy(struct eth_device *dev) 21 { 22 /*TODO for external PHY */ 23 24 return 0; 25 } 26 27 #ifdef DEBUG 28 static void ldpaa_eth_get_dpni_counter(void) 29 { 30 int err = 0; 31 u64 value; 32 33 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 34 dflt_dpni->dpni_handle, 35 DPNI_CNT_ING_FRAME, 36 &value); 37 if (err < 0) { 38 printf("dpni_get_counter: DPNI_CNT_ING_FRAME failed\n"); 39 return; 40 } 41 printf("DPNI_CNT_ING_FRAME=%lld\n", value); 42 43 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 44 dflt_dpni->dpni_handle, 45 DPNI_CNT_ING_BYTE, 46 &value); 47 if (err < 0) { 48 printf("dpni_get_counter: DPNI_CNT_ING_BYTE failed\n"); 49 return; 50 } 51 printf("DPNI_CNT_ING_BYTE=%lld\n", value); 52 53 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 54 dflt_dpni->dpni_handle, 55 DPNI_CNT_ING_FRAME_DROP , 56 &value); 57 if (err < 0) { 58 printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DROP failed\n"); 59 return; 60 } 61 printf("DPNI_CNT_ING_FRAME_DROP =%lld\n", value); 62 63 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 64 dflt_dpni->dpni_handle, 65 DPNI_CNT_ING_FRAME_DISCARD, 66 &value); 67 if (err < 0) { 68 printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DISCARD failed\n"); 69 return; 70 } 71 printf("DPNI_CNT_ING_FRAME_DISCARD=%lld\n", value); 72 73 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 74 dflt_dpni->dpni_handle, 75 DPNI_CNT_EGR_FRAME, 76 &value); 77 if (err < 0) { 78 printf("dpni_get_counter: DPNI_CNT_EGR_FRAME failed\n"); 79 return; 80 } 81 printf("DPNI_CNT_EGR_FRAME=%lld\n", value); 82 83 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 84 dflt_dpni->dpni_handle, 85 DPNI_CNT_EGR_BYTE , 86 &value); 87 if (err < 0) { 88 printf("dpni_get_counter: DPNI_CNT_EGR_BYTE failed\n"); 89 return; 90 } 91 printf("DPNI_CNT_EGR_BYTE =%lld\n", value); 92 93 err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 94 dflt_dpni->dpni_handle, 95 DPNI_CNT_EGR_FRAME_DISCARD , 96 &value); 97 if (err < 0) { 98 printf("dpni_get_counter: DPNI_CNT_EGR_FRAME_DISCARD failed\n"); 99 return; 100 } 101 printf("DPNI_CNT_EGR_FRAME_DISCARD =%lld\n", value); 102 } 103 #endif 104 105 static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 106 const struct dpaa_fd *fd) 107 { 108 u64 fd_addr; 109 uint16_t fd_offset; 110 uint32_t fd_length; 111 struct ldpaa_fas *fas; 112 uint32_t status, err; 113 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 114 u32 time_start; 115 struct qbman_release_desc releasedesc; 116 struct qbman_swp *swp = dflt_dpio->sw_portal; 117 118 fd_addr = ldpaa_fd_get_addr(fd); 119 fd_offset = ldpaa_fd_get_offset(fd); 120 fd_length = ldpaa_fd_get_len(fd); 121 122 debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 123 124 if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 125 /* Read the frame annotation status word and check for errors */ 126 fas = (struct ldpaa_fas *) 127 ((uint8_t *)(fd_addr) + 128 dflt_dpni->buf_layout.private_data_size); 129 status = le32_to_cpu(fas->status); 130 if (status & LDPAA_ETH_RX_ERR_MASK) { 131 printf("Rx frame error(s): 0x%08x\n", 132 status & LDPAA_ETH_RX_ERR_MASK); 133 goto error; 134 } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 135 printf("Unsupported feature in bitmask: 0x%08x\n", 136 status & LDPAA_ETH_RX_UNSUPP_MASK); 137 goto error; 138 } 139 } 140 141 debug("Rx frame: To Upper layer\n"); 142 net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 143 fd_length); 144 145 error: 146 flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); 147 qbman_release_desc_clear(&releasedesc); 148 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 149 time_start = get_timer(0); 150 do { 151 /* Release buffer into the QBMAN */ 152 err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 153 } while (get_timer(time_start) < timeo && err == -EBUSY); 154 155 if (err == -EBUSY) 156 printf("Rx frame: QBMAN buffer release fails\n"); 157 158 return; 159 } 160 161 static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 162 { 163 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 164 const struct ldpaa_dq *dq; 165 const struct dpaa_fd *fd; 166 int i = 5, err = 0, status; 167 u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 168 u32 time_start; 169 static struct qbman_pull_desc pulldesc; 170 struct qbman_swp *swp = dflt_dpio->sw_portal; 171 172 while (--i) { 173 qbman_pull_desc_clear(&pulldesc); 174 qbman_pull_desc_set_numframes(&pulldesc, 1); 175 qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 176 177 err = qbman_swp_pull(swp, &pulldesc); 178 if (err < 0) { 179 printf("Dequeue frames error:0x%08x\n", err); 180 continue; 181 } 182 183 time_start = get_timer(0); 184 185 do { 186 dq = qbman_swp_dqrr_next(swp); 187 } while (get_timer(time_start) < timeo && !dq); 188 189 if (dq) { 190 /* Check for valid frame. If not sent a consume 191 * confirmation to QBMAN otherwise give it to NADK 192 * application and then send consume confirmation to 193 * QBMAN. 194 */ 195 status = (uint8_t)ldpaa_dq_flags(dq); 196 if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 197 debug("Dequeue RX frames:"); 198 debug("No frame delivered\n"); 199 200 qbman_swp_dqrr_consume(swp, dq); 201 continue; 202 } 203 204 fd = ldpaa_dq_fd(dq); 205 206 /* Obtain FD and process it */ 207 ldpaa_eth_rx(priv, fd); 208 qbman_swp_dqrr_consume(swp, dq); 209 break; 210 } else { 211 err = -ENODATA; 212 debug("No DQRR entries\n"); 213 break; 214 } 215 } 216 217 return err; 218 } 219 220 static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 221 { 222 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 223 struct dpaa_fd fd; 224 u64 buffer_start; 225 int data_offset, err; 226 u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; 227 u32 time_start; 228 struct qbman_swp *swp = dflt_dpio->sw_portal; 229 struct qbman_eq_desc ed; 230 struct qbman_release_desc releasedesc; 231 232 /* Setup the FD fields */ 233 memset(&fd, 0, sizeof(fd)); 234 235 data_offset = priv->tx_data_offset; 236 237 do { 238 err = qbman_swp_acquire(dflt_dpio->sw_portal, 239 dflt_dpbp->dpbp_attr.bpid, 240 &buffer_start, 1); 241 } while (err == -EBUSY); 242 243 if (err < 0) { 244 printf("qbman_swp_acquire() failed\n"); 245 return -ENOMEM; 246 } 247 248 debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 249 250 memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 251 252 flush_dcache_range(buffer_start, buffer_start + 253 LDPAA_ETH_RX_BUFFER_SIZE); 254 255 ldpaa_fd_set_addr(&fd, (u64)buffer_start); 256 ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 257 ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 258 ldpaa_fd_set_len(&fd, len); 259 260 fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 261 LDPAA_FD_CTRL_PTV1; 262 263 qbman_eq_desc_clear(&ed); 264 qbman_eq_desc_set_no_orp(&ed, 0); 265 qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 266 267 time_start = get_timer(0); 268 269 while (get_timer(time_start) < timeo) { 270 err = qbman_swp_enqueue(swp, &ed, 271 (const struct qbman_fd *)(&fd)); 272 if (err != -EBUSY) 273 break; 274 } 275 276 if (err < 0) { 277 printf("error enqueueing Tx frame\n"); 278 goto error; 279 } 280 281 return err; 282 283 error: 284 qbman_release_desc_clear(&releasedesc); 285 qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 286 time_start = get_timer(0); 287 do { 288 /* Release buffer into the QBMAN */ 289 err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); 290 } while (get_timer(time_start) < timeo && err == -EBUSY); 291 292 if (err == -EBUSY) 293 printf("TX data: QBMAN buffer release fails\n"); 294 295 return err; 296 } 297 298 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 299 { 300 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 301 struct dpni_queue_attr rx_queue_attr; 302 struct dpmac_link_state dpmac_link_state = { 0 }; 303 #ifdef DEBUG 304 struct dpni_link_state link_state; 305 #endif 306 int err; 307 308 if (net_dev->state == ETH_STATE_ACTIVE) 309 return 0; 310 311 if (get_mc_boot_status() != 0) { 312 printf("ERROR (MC is not booted)\n"); 313 return -ENODEV; 314 } 315 316 if (get_dpl_apply_status() == 0) { 317 printf("ERROR (DPL is deployed. No device available)\n"); 318 return -ENODEV; 319 } 320 /* DPMAC initialization */ 321 err = ldpaa_dpmac_setup(priv); 322 if (err < 0) 323 goto err_dpmac_setup; 324 325 /* DPMAC binding DPNI */ 326 err = ldpaa_dpmac_bind(priv); 327 if (err) 328 goto err_dpamc_bind; 329 330 /* DPNI initialization */ 331 err = ldpaa_dpni_setup(priv); 332 if (err < 0) 333 goto err_dpni_setup; 334 335 err = ldpaa_dpbp_setup(); 336 if (err < 0) 337 goto err_dpbp_setup; 338 339 /* DPNI binding DPBP */ 340 err = ldpaa_dpni_bind(priv); 341 if (err) 342 goto err_dpni_bind; 343 344 err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 345 dflt_dpni->dpni_handle, net_dev->enetaddr); 346 if (err) { 347 printf("dpni_add_mac_addr() failed\n"); 348 return err; 349 } 350 351 #ifdef CONFIG_PHYLIB 352 /* TODO Check this path */ 353 err = phy_startup(priv->phydev); 354 if (err) { 355 printf("%s: Could not initialize\n", priv->phydev->dev->name); 356 return err; 357 } 358 #else 359 priv->phydev->speed = SPEED_1000; 360 priv->phydev->link = 1; 361 priv->phydev->duplex = DUPLEX_FULL; 362 #endif 363 364 err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 365 if (err < 0) { 366 printf("dpni_enable() failed\n"); 367 return err; 368 } 369 370 dpmac_link_state.rate = SPEED_1000; 371 dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG; 372 dpmac_link_state.up = 1; 373 err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 374 priv->dpmac_handle, &dpmac_link_state); 375 if (err < 0) { 376 printf("dpmac_set_link_state() failed\n"); 377 return err; 378 } 379 380 #ifdef DEBUG 381 err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 382 dflt_dpni->dpni_handle, &link_state); 383 if (err < 0) { 384 printf("dpni_get_link_state() failed\n"); 385 return err; 386 } 387 388 printf("link status: %d - ", link_state.up); 389 link_state.up == 0 ? printf("down\n") : 390 link_state.up == 1 ? printf("up\n") : printf("error state\n"); 391 #endif 392 393 /* TODO: support multiple Rx flows */ 394 err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 395 dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); 396 if (err) { 397 printf("dpni_get_rx_flow() failed\n"); 398 goto err_rx_flow; 399 } 400 401 priv->rx_dflt_fqid = rx_queue_attr.fqid; 402 403 err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 404 &priv->tx_qdid); 405 if (err) { 406 printf("dpni_get_qdid() failed\n"); 407 goto err_qdid; 408 } 409 410 if (!priv->phydev->link) 411 printf("%s: No link.\n", priv->phydev->dev->name); 412 413 return priv->phydev->link ? 0 : -1; 414 415 err_qdid: 416 err_rx_flow: 417 dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 418 err_dpni_bind: 419 ldpaa_dpbp_free(); 420 err_dpbp_setup: 421 err_dpamc_bind: 422 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 423 err_dpni_setup: 424 err_dpmac_setup: 425 return err; 426 } 427 428 static void ldpaa_eth_stop(struct eth_device *net_dev) 429 { 430 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 431 int err = 0; 432 433 if ((net_dev->state == ETH_STATE_PASSIVE) || 434 (net_dev->state == ETH_STATE_INIT)) 435 return; 436 437 #ifdef DEBUG 438 ldpaa_eth_get_dpni_counter(); 439 #endif 440 441 err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 442 dflt_dprc_handle, &dpmac_endpoint); 443 if (err < 0) 444 printf("dprc_disconnect() failed dpmac_endpoint\n"); 445 446 err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 447 if (err < 0) 448 printf("dpmac_destroy() failed\n"); 449 450 /* Stop Tx and Rx traffic */ 451 err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 452 if (err < 0) 453 printf("dpni_disable() failed\n"); 454 455 #ifdef CONFIG_PHYLIB 456 phy_shutdown(priv->phydev); 457 #endif 458 459 ldpaa_dpbp_free(); 460 dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 461 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 462 } 463 464 static void ldpaa_dpbp_drain_cnt(int count) 465 { 466 uint64_t buf_array[7]; 467 void *addr; 468 int ret, i; 469 470 BUG_ON(count > 7); 471 472 do { 473 ret = qbman_swp_acquire(dflt_dpio->sw_portal, 474 dflt_dpbp->dpbp_attr.bpid, 475 buf_array, count); 476 if (ret < 0) { 477 printf("qbman_swp_acquire() failed\n"); 478 return; 479 } 480 for (i = 0; i < ret; i++) { 481 addr = (void *)buf_array[i]; 482 debug("Free: buffer addr =0x%p\n", addr); 483 free(addr); 484 } 485 } while (ret); 486 } 487 488 static void ldpaa_dpbp_drain(void) 489 { 490 int i; 491 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 492 ldpaa_dpbp_drain_cnt(7); 493 } 494 495 static int ldpaa_bp_add_7(uint16_t bpid) 496 { 497 uint64_t buf_array[7]; 498 u8 *addr; 499 int i; 500 struct qbman_release_desc rd; 501 502 for (i = 0; i < 7; i++) { 503 addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 504 if (!addr) { 505 printf("addr allocation failed\n"); 506 goto err_alloc; 507 } 508 memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 509 flush_dcache_range((u64)addr, 510 (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 511 512 buf_array[i] = (uint64_t)addr; 513 debug("Release: buffer addr =0x%p\n", addr); 514 } 515 516 release_bufs: 517 /* In case the portal is busy, retry until successful. 518 * This function is guaranteed to succeed in a reasonable amount 519 * of time. 520 */ 521 522 do { 523 mdelay(1); 524 qbman_release_desc_clear(&rd); 525 qbman_release_desc_set_bpid(&rd, bpid); 526 } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 527 528 return i; 529 530 err_alloc: 531 if (i) 532 goto release_bufs; 533 534 return 0; 535 } 536 537 static int ldpaa_dpbp_seed(uint16_t bpid) 538 { 539 int i; 540 int count; 541 542 for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 543 count = ldpaa_bp_add_7(bpid); 544 if (count < 7) 545 printf("Buffer Seed= %d\n", count); 546 } 547 548 return 0; 549 } 550 551 static int ldpaa_dpbp_setup(void) 552 { 553 int err; 554 555 err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 556 &dflt_dpbp->dpbp_handle); 557 if (err) { 558 printf("dpbp_open() failed\n"); 559 goto err_open; 560 } 561 562 err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 563 if (err) { 564 printf("dpbp_enable() failed\n"); 565 goto err_enable; 566 } 567 568 err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 569 dflt_dpbp->dpbp_handle, 570 &dflt_dpbp->dpbp_attr); 571 if (err) { 572 printf("dpbp_get_attributes() failed\n"); 573 goto err_get_attr; 574 } 575 576 err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 577 if (err) { 578 printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 579 dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 580 goto err_seed; 581 } 582 583 return 0; 584 585 err_seed: 586 err_get_attr: 587 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 588 err_enable: 589 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 590 err_open: 591 return err; 592 } 593 594 static void ldpaa_dpbp_free(void) 595 { 596 ldpaa_dpbp_drain(); 597 dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 598 dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 599 dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 600 } 601 602 static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 603 { 604 int err = 0; 605 struct dpmac_cfg dpmac_cfg; 606 607 dpmac_cfg.mac_id = priv->dpmac_id; 608 err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg, 609 &priv->dpmac_handle); 610 if (err) 611 printf("dpmac_create() failed\n"); 612 return err; 613 } 614 615 static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 616 { 617 int err = 0; 618 struct dprc_connection_cfg dprc_connection_cfg = { 619 /* If both rates are zero the connection */ 620 /* will be configured in "best effort" mode. */ 621 .committed_rate = 0, 622 .max_rate = 0 623 }; 624 625 #ifdef DEBUG 626 struct dprc_endpoint dbg_endpoint; 627 int state = 0; 628 #endif 629 630 memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 631 strcpy(dpmac_endpoint.type, "dpmac"); 632 dpmac_endpoint.id = priv->dpmac_id; 633 634 memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 635 strcpy(dpni_endpoint.type, "dpni"); 636 dpni_endpoint.id = dflt_dpni->dpni_id; 637 638 err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 639 dflt_dprc_handle, 640 &dpmac_endpoint, 641 &dpni_endpoint, 642 &dprc_connection_cfg); 643 if (err) 644 printf("dprc_connect() failed\n"); 645 646 #ifdef DEBUG 647 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 648 dflt_dprc_handle, &dpni_endpoint, 649 &dbg_endpoint, &state); 650 printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 651 printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 652 printf("%s, DPMAC State= %d\n", __func__, state); 653 654 memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 655 err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 656 dflt_dprc_handle, &dpmac_endpoint, 657 &dbg_endpoint, &state); 658 printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 659 printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 660 printf("%s, DPNI State= %d\n", __func__, state); 661 #endif 662 return err; 663 } 664 665 static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 666 { 667 int err; 668 669 /* and get a handle for the DPNI this interface is associate with */ 670 err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 671 &dflt_dpni->dpni_handle); 672 if (err) { 673 printf("dpni_open() failed\n"); 674 goto err_open; 675 } 676 677 err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 678 dflt_dpni->dpni_handle, 679 &dflt_dpni->dpni_attrs); 680 if (err) { 681 printf("dpni_get_attributes() failed (err=%d)\n", err); 682 goto err_get_attr; 683 } 684 685 /* Configure our buffers' layout */ 686 dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 687 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 688 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 689 DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 690 dflt_dpni->buf_layout.pass_parser_result = true; 691 dflt_dpni->buf_layout.pass_frame_status = true; 692 dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 693 /* HW erratum mandates data alignment in multiples of 256 */ 694 dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 695 /* ...rx, ... */ 696 err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 697 dflt_dpni->dpni_handle, 698 &dflt_dpni->buf_layout); 699 if (err) { 700 printf("dpni_set_rx_buffer_layout() failed"); 701 goto err_buf_layout; 702 } 703 704 /* ... tx, ... */ 705 /* remove Rx-only options */ 706 dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 707 DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 708 err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 709 dflt_dpni->dpni_handle, 710 &dflt_dpni->buf_layout); 711 if (err) { 712 printf("dpni_set_tx_buffer_layout() failed"); 713 goto err_buf_layout; 714 } 715 716 /* ... tx-confirm. */ 717 dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 718 err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 719 dflt_dpni->dpni_handle, 720 &dflt_dpni->buf_layout); 721 if (err) { 722 printf("dpni_set_tx_conf_buffer_layout() failed"); 723 goto err_buf_layout; 724 } 725 726 /* Now that we've set our tx buffer layout, retrieve the minimum 727 * required tx data offset. 728 */ 729 err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 730 dflt_dpni->dpni_handle, 731 &priv->tx_data_offset); 732 if (err) { 733 printf("dpni_get_tx_data_offset() failed\n"); 734 goto err_data_offset; 735 } 736 737 /* Warn in case TX data offset is not multiple of 64 bytes. */ 738 WARN_ON(priv->tx_data_offset % 64); 739 740 /* Accomodate SWA space. */ 741 priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 742 debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 743 744 return 0; 745 746 err_data_offset: 747 err_buf_layout: 748 err_get_attr: 749 dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 750 err_open: 751 return err; 752 } 753 754 static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 755 { 756 struct dpni_pools_cfg pools_params; 757 struct dpni_tx_flow_cfg dflt_tx_flow; 758 int err = 0; 759 760 pools_params.num_dpbp = 1; 761 pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 762 pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 763 err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 764 dflt_dpni->dpni_handle, &pools_params); 765 if (err) { 766 printf("dpni_set_pools() failed\n"); 767 return err; 768 } 769 770 priv->tx_flow_id = DPNI_NEW_FLOW_ID; 771 memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); 772 773 dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR; 774 dflt_tx_flow.conf_err_cfg.use_default_queue = 0; 775 dflt_tx_flow.conf_err_cfg.errors_only = 1; 776 err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 777 dflt_dpni->dpni_handle, &priv->tx_flow_id, 778 &dflt_tx_flow); 779 if (err) { 780 printf("dpni_set_tx_flow() failed\n"); 781 return err; 782 } 783 784 return 0; 785 } 786 787 static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 788 phy_interface_t enet_if) 789 { 790 int err; 791 struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 792 793 sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id, 794 phy_interface_strings[enet_if]); 795 796 net_dev->iobase = 0; 797 net_dev->init = ldpaa_eth_open; 798 net_dev->halt = ldpaa_eth_stop; 799 net_dev->send = ldpaa_eth_tx; 800 net_dev->recv = ldpaa_eth_pull_dequeue_rx; 801 /* 802 TODO: PHY MDIO information 803 priv->bus = info->bus; 804 priv->phyaddr = info->phy_addr; 805 priv->enet_if = info->enet_if; 806 */ 807 808 if (init_phy(net_dev)) 809 return 0; 810 811 err = eth_register(net_dev); 812 if (err < 0) { 813 printf("eth_register() = %d\n", err); 814 return err; 815 } 816 817 return 0; 818 } 819 820 int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 821 { 822 struct eth_device *net_dev = NULL; 823 struct ldpaa_eth_priv *priv = NULL; 824 int err = 0; 825 826 827 /* Net device */ 828 net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 829 if (!net_dev) { 830 printf("eth_device malloc() failed\n"); 831 return -ENOMEM; 832 } 833 memset(net_dev, 0, sizeof(struct eth_device)); 834 835 /* alloc the ldpaa ethernet private struct */ 836 priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 837 if (!priv) { 838 printf("ldpaa_eth_priv malloc() failed\n"); 839 return -ENOMEM; 840 } 841 memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 842 843 net_dev->priv = (void *)priv; 844 priv->net_dev = (struct eth_device *)net_dev; 845 priv->dpmac_id = dpmac_id; 846 debug("%s dpmac_id=%d\n", __func__, dpmac_id); 847 848 err = ldpaa_eth_netdev_init(net_dev, enet_if); 849 if (err) 850 goto err_netdev_init; 851 852 debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 853 return 0; 854 855 err_netdev_init: 856 free(priv); 857 net_dev->priv = NULL; 858 free(net_dev); 859 860 return err; 861 } 862