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